线程使用存储过程访问数据库,运行时提示“在异步运行时,操作不能被执行”,请行家看看并赐教!(200分)

  • 主题发起人 leijh001
  • 开始时间
L

leijh001

Unregistered / Unconfirmed
GUEST, unregistred user!
constructor transthread.Create(Mm1: TMemo;
Num_: integer;
StoredP: TADOStoredProc;
FSTRING: string;
usetime: Int64;
con_: TADOConnection);
begin
InitializeCriticalSection(cs);
CoInitialize(nil);
TmpNum := Num_;
TmpM1 := Mm1;
if FSTRING <> '' then
Strfram := FSTRING else
setframes(TmpM1);
FStoredP := StoredP;
FStoredP.Close;
FStoredP.ProcedureName := 'analyseframe;1';
FStoredP.Connection := con_;
FStoredP.Parameters.Clear;
FStoredP.Parameters.CreateParameter('@receiveframe', ftString, pdInput, 8000, fgUnassigned);
FStoredP.Parameters.CreateParameter('@returnframe', ftString, pdOutput, 6000, fgUnassigned);
FStoredP.Parameters[0].Value := Strfram;
FStoredP.Parameters[1].Value := '';
fusetime := usetime;
FreeOnTerminate := true;
// Have thread object free itself when terminated
inherited Create(false);
// Create thread in a suspendend state
end;

procedure transthread.Execute;
begin
try
FStoredP.Prepared;
FStoredP.ExecProc;
EnterCriticalSection(cs);
begin
Synchronize(retDataMemo);
// 同步
Synchronize(returnprovalue);
end;
LeaveCriticalSection(cs);
CoUninitialize;
except
CoUninitialize;
FQueryException := ExceptObject as Exception;
Synchronize(ShowQryError);
LeaveCriticalSection(cs);
end;
{ Place thread code here }
end;
 
ADO有同步执行和异步执行两个模式
异步模式在调用后立即返回,并通过ado的事件进行结果响应
同步模式就和最平常的调用方式一样,调用完成后返回结果
多线程下应该使用同步模式(默认)
出现“在异步运行时,操作不能被执行”的原因如下:
1.ADO数据组件的ExecuteOptions中,设置了eoAsyncExecute等标志,且反复调用,没正确响应事件调整状态
2.或者多个线程同时操作同一ADO组件
3.其它COM方面的错误
我看老兄你的代码中有个明显的COM错误:
在Thread.Create方法中调用了 CoInitialize(nil);
在Thread.execute方法结尾处调用了CoUninitialize;
前者执行线程通常是主线程
后者执行的是Thread本身, 两者不相同,则谬以千里也~~~
正常方法:
procedure thread.execute;
begin
CoInitialize(nil);
try
... 操作ADO的代码
finally
CoUninitialize;
end;
end;
 
说得有点道理,但按照你的方法,还是照样报同样的错
 
procedure transthread.Execute;
begin
CoInitialize(nil);
try
EnterCriticalSection(cs);
begin
FStoredP.Prepared;
// 同步
FStoredP.ExecProc;
retDataMemo;
returnprovalue;
end;

finally
LeaveCriticalSection(cs);
CoUninitialize;
end;
{ Place thread code here }
end;

别的地方访问同一个数据库连接的地方都是加临界区
如果这样做你觉得订麻烦,就干脆在线程新建的connection
 
一个线程 用一个Adoconnction ,
 
我提到的3个会引起“在异步运行时,操作不能被执行”的原因,请核实每一个都没有发生。--特别是第2个
我上面改写的只是一个例子而已,而不是全部。
正确的写法和做法如果有一个的话,那么错误的写法就是千千百百,写程序很大部分就是一个除错的过程。
 
问题已解决。如fanronghua所说,一个线程一个ADO。在创建新线程时,新建一个ADO。
 
顶部