关于线程使用的问题(100分)

L

ljlboy

Unregistered / Unconfirmed
GUEST, unregistred user!
我想做一个语音卡(480路通道)的应用程序,我在timer中每隔50毫秒检测一遍通道,如果发现摘机的话,就开启一个线程处理摘机以后的事情,在线程中我要多次访问DataMoudle中的一个Query(只是用到Locate方法).问题是程序老是出错,
一运行就黑屏了.
是不是一定要再开启一个线程来处理数据库?与session有什么关系?synchronize()是不是一定要使用?有没有什么好的方案?
 
操纵vcl组件时一定要用synchronize()
你应该在线程中动态的创建一个Tquery来处理数据
 
线程里面的query,需要有独立的session。以下为解决的一个方法
procedure createqry(Qry:Tquery);
begin
qry:=Tquery.create(nil);
try
Session.SessionName := Format('%s%x', [Session.Name, UniqueNumber]);
Database.DriverName := FdriverName;
Database.Params.Values['SERVER NAME'] :=FServerName;
Database.Params.Values['USER NAME'] := FUserName;
Database.Params.Values['PASSWORD'] :=FPassword;
Database.SessionName := Session.SessionName;
Database.DatabaseName := Format('%s%x', [Database.Name, UniqueNumber]);
Qry.SessionName := Database.SessionName;
Qry.DatabaseName := Database.DatabaseName;
//以下处理要做的事情,释放也可以在其它函数中进行
fianlly
qry.free;
end;
end;

其中GetUniqueNumber是为了保持唯一性,可以这么写
var
Guard: Integer;
Numbers: Integer;
function GetUniqueNumber: Integer;
asm
@@1: MOV EDX,1
XCHG Guard,EDX
OR EDX,EDX
JNZ @@2
MOV EAX,Numbers
INC EAX
MOV Numbers,EAX
MOV Guard,EDX
RET
@@2: PUSH 0
CALL Sleep
JMP @@1
end;
 
Query必须重新创建?
 
在访问的时候要注意线程的互斥,可以建立TMultiReadExclusiveWriteSynchronizer对象来解决。
gMulReadExcWriteA:TMultiReadExclusiveWriteSynchronizer;
在需要时创建,
读内存同步:gMulReadExcWriteA.begin
read;
gMulReadExcWriteA.endread;
写内存同步:gMulReadExcWriteA.begin
write;
gMulReadExcWriteA.endwrite;
 
不需要,根据自己需要,也可以直接在外面放一个query控件,在线程里面,要保证session的唯一性。
 
Session.SessionName := Format('%s%x', [Session.Name, UniqueNumber]);
上面这句子话会出现
' cannot perform this operation on an active session'的错误
 
多人接受答案了。
 
顶部