首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > .NET >

请问 Delphi 多线程切换输入法后程序假死了

2013-07-11 
请教 Delphi 多线程切换输入法后程序假死了最近遇到程序开启线程后,在主界面编辑框中切换输入法,程序就卡

请教 Delphi 多线程切换输入法后程序假死了
最近遇到程序开启线程后,在主界面编辑框中切换输入法,程序就卡住,只有强制关闭了
线程里只有一个ADODataSet和一个ADOCommand,创建后从设备取数据存入数据库中。
以前类似的线程运行都没问题,现在问题出现后重装输入法,换电脑没能解决。
网上说因为线程中创建了窗口,消息死锁了,但在接收设备数据的时候,没有数据是等待状态 ,循环也处于等待中,执行不了消息解除死锁的过程。
不明白的是类似线程用过不少次了,为什么同样的环境 ,同样的方式 ,现在就出现了这情况了呢?
请高手指点指点!
Delphi? 多线程切换输入法? 假死 消息死锁
[解决办法]
线程里不要操作窗体,如果需要使用消息的方式。
[解决办法]

function TCFADODBStorage.OpenConnection: Boolean;

  //线程里打开ADOConnection,在XP下切换输入法程序会死掉
  //原因:ADO自动创建一个ADODB.AsyncEventMessenger窗口,然后会有一个对应的IME窗口,但线程里没有消息循环
  //     XP下输入法切换时会SendMessage给IME窗口并等待返回,IME窗口并不会处理消息,造成死锁
  //这个函数把线程里的IME窗口释放掉,切换输入法时就不会有消息过来了
  procedure _FreeIMEWindow;
  const
    IME_WINDOW_CLASS = 'IME';
    IME_WINDOW_TEXT  = 'Default IME';
  var
    h : HWND;
    pid : DWORD;
    dh : HWND;
  begin
    h :=  FindWindow(IME_WINDOW_CLASS, IME_WINDOW_TEXT);
    while IsWindow(h) do
    begin
      if GetWindowThreadProcessId(h, pid) = GetCurrentThreadId then
        dh  :=  h
      else
        dh  :=  0;
      h :=  FindWindowEx(0, h, IME_WINDOW_CLASS, IME_WINDOW_TEXT);
      if dh <> 0 then
        DestroyWindow(dh);
    end;
  end;

begin
  try
    FConnection.ConnectionString  :=  ConnectionString;
    FConnection.Connected :=  True;


    if GetCurrentThreadId <> Global.MainThreadID{全局的主线程ID,如果是主线程,不需要Free} then
      _FreeIMEWindow;
  except on E: Exception do
    FLastErrorMessage :=  e.Message;
  end;
  Result  :=  FConnection.Connected;
end;


[解决办法]
线程中要加入消息条件退出语句,这样才不能无限循环(假死)。

热点排行