//執行緒類如下
type
Tusercj = class(TThread)
user: string;
pass: string;
name: string; //昵稱
date_str: string; //采集日期
date_t: tDate; //采集日期
Date_curr: TDate; //現在的日期 采集當前的日期
get_day: Integer; //需要采集的天數
htmlcode: string;
str: string;
error_count: Integer; //出現錯誤統計
tab: TTabSheet;
memo: TmxMemo; //日志框
param: TStringList; //POST提交引數
idssl: TIdSSLIOHandlerSocket; //SSL需要的
idhttp: TIdHTTP; //POST獲取資料控制元件
vercode: TMemoryStream; //驗證碼檔案位元組
qry, qry1, qry2: TADOQuery;
protected
procedure Execute; override; //執行緒啟使
procedure main(); //采集主函式
procedure data_count(); //資料統計
procedure save_xml(); //生成XML
procedure log(str: string); //日志
function get_data(): Integer; //獲取指定日期資料
function check_error(): Boolean; //檢查是否達到最大錯誤
function selectuser(): Boolean; //檢查當天日期的資料是否存在
function get_vercode(): string; //獲取驗證碼
end;
Execute;下有進行TAB和M的Create
tab := TTabSheet.Create(Form1.pgc1);
tab.Caption := self.user;
tab.Parent := Form1.pgc1;
tab.PageControl := Form1.pgc1;
tab.Align := alClient;
memo := tmxmemo.Create(tab);
memo.Parent := tab;
memo.Align := alClient;
問題是 創建的MEMO 不接收任何訊息和事件,比如像上面這樣寫 MEMO正常顯示 但在上面添加一句memo.lines.add('text'); MEMO在表單上就顯示不出來了,用sendmessage發送訊息也接受不了,但如果創建后 手動點開表單上的MEMO,再用sendmessage發送訊息,又可以正常接收,
問題就是 為什么MEMO會不正常顯示
uj5u.com熱心網友回復:
這是一個執行緒安全問題。不應在執行緒里創建及訪問界面元素。
建議:在準備好資料后,通過SendeMessage訊息給主表單,告訴主表單已處理完畢。這時主表單可掛起該執行緒(看你的需要),構造界面元素并讀取執行緒類準備好的資料.....
uj5u.com熱心網友回復:
多謝版主大人,但我現在的問題是,memo是要現實執行緒執行的日志,可以看到上面有一個LOG程序,就是就sendmessage發送給創建的memo資料用的,處理完畢再構建肯定是不行的uj5u.com熱心網友回復:
log資料采集程序?
總之,你的界面創建及訪問,一定不能在執行緒中。
如果考慮log程序,那么就應在執行緒啟動前,將界面提前準備好就行了。
執行緒execute時,postmessage附帶讀取資料提交給主執行緒,主表單處理此訊息,添加相關資料到Memo中。
uj5u.com熱心網友回復:
execute是初始化各種資料和控制元件main是采集的主程序
log下面是一個sendmessage發送日志的訊息 是發送給本執行緒類下的MEMO的
我這樣寫是想好控制,如果先把MEMO創建好,執行緒都不知道要將日志發送到哪個MEMO上 又要用到回圈去讀取MEMO的資料才好確定發送到哪個MEMO上 這樣效率是不是太慢了
uj5u.com熱心網友回復:
首先,再說明一下不要在執行緒里做 界面設定;
其次,“如果先把MEMO創建好,執行緒都不知道要將日志發送到哪個MEMO上”,你完全可以在發送訊息時附帶執行緒的標識,通過此標識確定Memo(界面的初始化與執行緒創建,可以在同一位置處理并關聯起來)。
問題其實不復雜,多思考思考。不要因為一點小問題,去走“彎路”,到時還得繞回來
uj5u.com熱心網友回復:
delphi 執行緒存取ui控制元件, 要同步~~~~要同步~~uj5u.com熱心網友回復:
控制元件屬于UI,要回到主執行緒更新內容。uj5u.com熱心網友回復:
參考一下 TTimer 代碼,收到訊息后,更新 Memo。
uj5u.com熱心網友回復:
這位同學說的對,執行緒要使用同步函式操作界面,好像是syncronize函式,你查查幫助吧
uj5u.com熱心網友回復:
執行緒不要直接使用界面元素,Delphi的視窗,控制元件都應該在主執行緒訪問.syncronize是可以的,因為它是發訊息給主執行緒,在主執行緒里面執行的uj5u.com熱心網友回復:
多載執行緒的建構式,在建構式中將主界面中的memo當做引數傳遞給執行緒中,然后使用就沒有問題。你在執行緒的執行函式中創建這些肯定是不行的!uj5u.com熱心網友回復:
在執行緒中定義一個Memo物件_Memo:TMemo;
多載執行緒單元建構式
public
//多載建構式(這里定 義多少引數都可以
constructor Create(aMemo:TMemo);
//多載解構式
Destructor Destroy; override;
//執行緒構函式函式(所有需要初始化的部分都寫到這里面)
constructor TNetThread.Create(aMemo:TMemol);
begin
_Memo := aMemo;
FreeOnTerminate:=true; //標志著執行緒執行完畢后,自動釋放資源
inherited Create(true); //執行緒創建時不執行,指定運行后方才執行(如果是false則創建后立即執行)
end;
//執行緒解構式(執行緒結束后釋放資源)
destructor TNetThread.Destroy;
begin
_Memo := nil;
inherited;
end;
//執行緒執行函式
procedure TNetThread.Execute;
begin
_memo.lines.add('執行成功了');
end;
uj5u.com熱心網友回復:
估計你的Execute里修改memo后還的加一句,application.processMessage把訊息發到主執行緒去更新界面uj5u.com熱心網友回復:
不需要Application.processMessage,直接改就可以看到,我經常這樣用。Application.processMessage是在同一主執行緒中需要重繪控制元件時使用(此時可能有一個耗的操作在執行).
uj5u.com熱心網友回復:
直接 SendMessage 給 Memo!轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/107262.html
