一、多张线程与界面处理

1.子线程千万不要访问主线程的UI,(memo,Label),我发现这样做的程序员很多,在diocp中经常会用到onConnected/OnDisconnected事件中直接操作主窗体的Memo。导致程序无法正常退出,或者出现卡死主界面的情况,原因我想可以归纳到访问冲突上面,用临界也不能解决问题。很多组件都是靠windows消息驱动,他才不会使用零件去处理消息,所以临界也没办法。你只有老老实实的投递到主线程去完成这部分工作,qworker和iocpTask都可以很好的完成这项工作。

2.线程之间访问共享资源需要用临界,千万不要多个线程同时去处理同一个变量,或者列表,否则就等着出现各种问题吧。

3.数据库连接尽量用连接池去完成,这样既可以减少连接,也可以很好的避免多个线程对同一个连接的使用。

问题1网友的解决方案要:

Delphi主线程重入而导致程序卡死的解决方案

 

Delphi的线程可以通过调用AThread.Synchronize(AProc),可以将Proc放入主线程中同步运行,此时AThread将挂起,直到主线程执行完AProc。

如果有BThread,调用了BThread.Synchronize(BProc),而BProc中释放了AThread

procedure TBThread.BProc
begin
  AThread.Terminate;
  AThread.WaitFor;
  AThread.Free;
end;

此时我们的程序将会卡死,下面的代码可以避免死锁,是通用的线程等待结束代码。

 

复制代码
    AThread.Terminate;
    while not AThread.Finished do
    begin
      if GetCurrentThreadID = MainThreadID then  //由于是通过Synchronize同步到主线程执行,所以调用CheckSynchronize,防止死锁
        CheckSynchronize(0);

      Sleep(1);
    end;
    FreeAndNil(AThread);
复制代码

 如果以前没注意此重入问题,请修改你的代码吧。因为不能保证我们的代码被其他人用时不会出现重入。

此代码既支持Windows,也支持Android

不过包含的单元不一样:

复制代码
uses System.SyncObjs,
{$ifdef MSWINDOWS}
Windows;
{$endif}
{$ifdef POSIX}
Posix.Pthread;
{$endif}
复制代码