我回来了另一个有关线程和同步的问题。想象一个服务器应用程序必须执行冗长的操作,并且客户端希望他的GUI在等待服务器响应时保持响应状态。我想到了以下模式:
TMonitor.Enter (FTCPClient);
try
WorkerThread := TWorkerThread.Create (SomeLengthyServerOperation);
while (not WorkerThread.Ready) do
Application.ProcessMessages;
DoSometingWithResults (WorkerThread.Result);
WorkerThread.Free;
finally
TMonitor.Exit (FTCPClient);
end;
WorkerThread是从TThread派生的简单类,该类执行传递给其构造函数的函数,然后终止(Ready = True,结果存入Result)。只要单击按钮,就会执行显示的代码。
现在我的问题是:如果我快速单击两次按钮,会出现一些奇怪的错误,看起来很像服务器和客户端之间的通信错误,我想通过锁定FTCPClient对象来避免这种错误。在执行Application.ProcessMessages之后,事件处理程序在哪个线程中进行?是否每个线程都锁定TMonitor?这是否意味着如果我使用Application.ProcessMessages,该锁将不起作用?
我现在无法更好地解释它。我希望有人能理解我的意思。如果没有,请随时提问。
编辑:对于按钮的禁用和启用:我对客户端代码一无所知。可能是按钮事件处理程序,也可能是其他事件。基本上,我想从客户端代码中隐藏锁定。
最佳答案
TMonitor仅阻止另一个的线程获取锁。这是怎么回事:通过处理锁中的消息,您将返回同一线程中的同一函数,这将导致递归获取锁。然后,您的代码将创建一个新的工作线程,并从头开始整个循环。您可以禁用该按钮,以便在辅助线程完成之前无法再次单击它。确保在开始处理消息之前禁用按钮,然后使用另一个try..finally块以确保重新启用它。根据其余代码的排列方式,您甚至可能不需要锁。
关于multithreading - TMonitor同步/Application.ProcessMessages,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/570052/