启动多线程向memo中写日志,我想达到的效果如下:
正在连接数据库......完成!
正在检查并创建目录......完成!
正在断开数据库连接......完成!
正在导出文件chongqing_bizict_sf_YYYY-MM......完成!
但在实际执行过程中几乎都没有出现国这样的情况,可能的情况比如:
正在连接数据库......
正在检查并创建目录......完成!完成!
正在断开数据库连接......
正在导出文件chongqing_bizict_sf_YYYY-MM......完成!完成!
主要的代码如下,大家看看有啥好办法解决:procedure TForm1.Button1Click(Sender: TObject);
begin
if Button1.Enabled then Button1.Enabled := False; CloseHandle(hSemaphore); //不知是不是之前创建过 Semaphore 对象, 假如有先关闭
hSemaphore := CreateSemaphore(nil, 1, 5, nil); //创建Semaphore对象,初始化为1个信号 WriteLog('N正在连接数据库......');
ConnectToDB; //连接数据库
WriteLog('A完成!'); WriteLog('N正在检查并创建目录......');
CheckDir; //检查数据存放目录是否存在,若不存在则创建
WriteLog('A完成!'); WriteLog('N正在导出文件chongqing_bizict_sf_YYYY-MM......');
BizictSFTimeCols := [11, 13, 21];
BusiLogic.TableToFile( ADOQuery1
,TouchSql(1)
,BizictSFTimeCols
,1);
WriteLog('A完成!'); WriteLog('N正在断开数据库连接......');
ADOConnection1.Connected := False;
WriteLog('A完成!');
end;//向Memo中写日志
procedure TForm1.WriteLog(MemoString : string);
var
PtMemo : pointer; //指向MemoString的指针
ThreadID : DWORD; //创建的线程ID
begin
PtMemo := pointer(MemoString);
CreateThread(nil, 0, @MyThreadFun, PtMemo, 0, ThreadID);
end;//多线程,往Memo中写信息
function MyThreadFun(p: Pointer): DWORD; stdcall;
var
Ptstr : pchar;
MemoStr : string; //要写入Memo的内容
FisrtChar : string; //传进来的字符串的首位,如果为"N",则新增一行;如果为"A",则在本行末尾添加
begin
if WaitForSingleObject(hSemaphore, INFINITE) = WAIT_OBJECT_0 then
begin
Ptstr := pchar(p);
MemoStr := strpas(Ptstr);
FisrtChar := copy(MemoStr,1,1);
MemoStr := copy(MemoStr,2,length(MemoStr) - 1);
Sleep(1);
if FisrtChar = 'N' then
CurrRowNum := Form1.Memo1.Lines.Add(MemoStr)
else if FisrtChar = 'A' then
Form1.Memo1.Lines.Strings[CurrRowNum] := Form1.Memo1.Lines.Strings[CurrRowNum] + MemoStr
else
CurrRowNum := Form1.Memo1.Lines.Add(MemoStr);
end; ReleaseSemaphore(hSemaphore, 1, nil); //让出信号给其他线程
Result := 0;
end;
正在连接数据库......完成!
正在检查并创建目录......完成!
正在断开数据库连接......完成!
正在导出文件chongqing_bizict_sf_YYYY-MM......完成!
但在实际执行过程中几乎都没有出现国这样的情况,可能的情况比如:
正在连接数据库......
正在检查并创建目录......完成!完成!
正在断开数据库连接......
正在导出文件chongqing_bizict_sf_YYYY-MM......完成!完成!
主要的代码如下,大家看看有啥好办法解决:procedure TForm1.Button1Click(Sender: TObject);
begin
if Button1.Enabled then Button1.Enabled := False; CloseHandle(hSemaphore); //不知是不是之前创建过 Semaphore 对象, 假如有先关闭
hSemaphore := CreateSemaphore(nil, 1, 5, nil); //创建Semaphore对象,初始化为1个信号 WriteLog('N正在连接数据库......');
ConnectToDB; //连接数据库
WriteLog('A完成!'); WriteLog('N正在检查并创建目录......');
CheckDir; //检查数据存放目录是否存在,若不存在则创建
WriteLog('A完成!'); WriteLog('N正在导出文件chongqing_bizict_sf_YYYY-MM......');
BizictSFTimeCols := [11, 13, 21];
BusiLogic.TableToFile( ADOQuery1
,TouchSql(1)
,BizictSFTimeCols
,1);
WriteLog('A完成!'); WriteLog('N正在断开数据库连接......');
ADOConnection1.Connected := False;
WriteLog('A完成!');
end;//向Memo中写日志
procedure TForm1.WriteLog(MemoString : string);
var
PtMemo : pointer; //指向MemoString的指针
ThreadID : DWORD; //创建的线程ID
begin
PtMemo := pointer(MemoString);
CreateThread(nil, 0, @MyThreadFun, PtMemo, 0, ThreadID);
end;//多线程,往Memo中写信息
function MyThreadFun(p: Pointer): DWORD; stdcall;
var
Ptstr : pchar;
MemoStr : string; //要写入Memo的内容
FisrtChar : string; //传进来的字符串的首位,如果为"N",则新增一行;如果为"A",则在本行末尾添加
begin
if WaitForSingleObject(hSemaphore, INFINITE) = WAIT_OBJECT_0 then
begin
Ptstr := pchar(p);
MemoStr := strpas(Ptstr);
FisrtChar := copy(MemoStr,1,1);
MemoStr := copy(MemoStr,2,length(MemoStr) - 1);
Sleep(1);
if FisrtChar = 'N' then
CurrRowNum := Form1.Memo1.Lines.Add(MemoStr)
else if FisrtChar = 'A' then
Form1.Memo1.Lines.Strings[CurrRowNum] := Form1.Memo1.Lines.Strings[CurrRowNum] + MemoStr
else
CurrRowNum := Form1.Memo1.Lines.Add(MemoStr);
end; ReleaseSemaphore(hSemaphore, 1, nil); //让出信号给其他线程
Result := 0;
end;
线程的代码放到Execute里
写窗口时用Synchronize回调
Execute结束时会自动销毁线程和对象。
按照你现在的代码, 得到正在连接数据库......
正在检查并创建目录......完成!完成!
正在断开数据库连接......
正在导出文件chongqing_bizict_sf_YYYY-MM......完成!完成! 这样的运行结果是很有可能的。在其他机器或系统中, 还可能会得到另外的运行结果。