全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:1959
推到 Plurk!
推到 Facebook!

在線程中使用TADOConnection導致程序停止呼應

缺席
h@visli
資深會員


發表:103
回覆:429
積分:431
註冊:2004-02-13

發送簡訊給我
#1 引用回覆 回覆 發表時間:2008-02-29 16:32:21 IP:219.133.xxx.xxx 未訂閱
由於我有頻繁的數據庫寫入操作,所以我用一個專門的線程來處理,在該線程中創建了一個TADOConnection組件,
現在發現當在程序中按下Ctrl Shift或Ctrl Space鍵(即切換輸入法)時,程序就死了!

我寫了一個簡單的Demo給大家看,附件中還有Demo的源文件。
Demo運行後,可以正常按下Ctrl Shift或Ctrl Space鍵,
但當按下Button1創建並執行線程後,再按Ctrl Shift或Ctrl Space鍵就會導致程序死掉。
請各位高手幫忙研究一下。

[code delphi]
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ActiveX, StdCtrls, DB, ADODB;

type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Button2: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

TDBThread = class(TThread)
private
protected
procedure Execute; override;
public
constructor Create;
end;

var
Form1: TForm1;
DBThread: TDBThread;

implementation

{$R *.dfm}

constructor TDBThread.Create;
begin
inherited Create(False);
FreeOnTerminate := True;
end;

procedure TDBThread.Execute;
var
DBConnection: TADOConnection;
begin
if CoInitializeEx(nil, COINIT_APARTMENTTHREADED) <> S_OK then
raise Exception.Create(SysErrorMessage(GetLastError));

DBConnection := TADOConnection.Create(nil);
try
while not Terminated do
Sleep(500);
finally
DBConnection.Free;
CoUninitialize;
end;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
DBThread := TDBThread.Create;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
DBThread.Terminate;
end;

end.

[/code]

------
------------------------
博采眾家之長,奉獻綿薄之力
------------------------
附加檔案:47c7c31517a1d_IME.rar
編輯記錄
taishyang 重新編輯於 2008-02-29 17:28:48, 註解 無‧
h@visli
資深會員


發表:103
回覆:429
積分:431
註冊:2004-02-13

發送簡訊給我
#2 引用回覆 回覆 發表時間:2008-03-03 09:16:25 IP:58.61.xxx.xxx 未訂閱
我發現這個問題與我上次遇到的是同一個問題:delphi.ktop.com.tw/board.php
我用Spy (Visual Studio Tools)查看,發現創建線程後,會出現兩個隱含的窗口:
窗口類:ADODB.AsyncEventMessenger, 標題爲空,
窗口類:IME,標題爲"Default IME"

我發現提供了輸入法服務(IME)的Windows操作系統中(英文操作系統就不存在這個問題),一個線程中(包括主線程)衹要創建了一個窗口對象,Windows就會幫助創建一個IME窗口,來接收 WM_IME_* 系列消息,提供IME服務。所以上面的"Default IME"窗口就是Windows默認創建的一個IME消息服務窗口,因爲線程中的TADOConnection創建時會隱匿地創建一個ADODB.AsyncEventMessenger類型的窗口。

而,
當進行輸入法切換時,是使用SendMessage函數向所有IME窗口廣播WM_IME_*消息的,我猜想會不會是由於線程中的TADOConnection組件內部又進行了同步操作,導致與SendMessage相衝突了呢?

希望高手們來討論一下,或請英文好的朋友能把我的這個問題Post到CodeGear新聞組: borland.public.delphi.language.delphi.win32
------
------------------------
博采眾家之長,奉獻綿薄之力
------------------------
編輯記錄
h@visli 重新編輯於 2008-03-03 09:19:42, 註解 無‧
malanlk
尊榮會員


發表:20
回覆:694
積分:577
註冊:2004-04-19

發送簡訊給我
#3 引用回覆 回覆 發表時間:2008-03-10 12:49:10 IP:218.211.xxx.xxx 訂閱
改成這樣就不會當掉了
while not Terminated do
begin
Application.ProcessMessages;
Sleep(50);
end;
系統時間:2024-05-05 4:51:08
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!