从线程调用远程SOAP调用的异常

Dun*_*can 4 delphi multithreading soap web-services

这是几分钟前我问过的这个问题的扩展/下一步.

我有一个主表单和线程的Delphi应用程序.每隔X秒,线程就会对远程对象发出Web服务请求.然后它回发到主窗体,它处理用新信息更新UI.

我以前在我的线程中使用了TTimer对象,当TTimer回调函数运行时,它在主线程的上下文中运行(但远程Web服务请求确实有效).这反而破坏了单独线程的目的,所以我现在在我的线程的Execute函数中有一个简单的循环和睡眠例程.问题是,从GetIMySOAPService()返回时会抛出异常.

procedure TPollingThread.Execute;
var
SystemStatus : TCWRSystemStatus;
begin
while not Terminated  do
begin
  sleep(5000);
  try
    SystemStatus := GetIMySOAPService().GetSystemStatus;
    PostMessage( ParentHandle, Integer(apiSystemStatus), Integer(SystemStatus), 0 );
    SystemStatus.DataContext := nil;
    LParam(SystemStatus) := 0;
  except
  end;
end;
end;
Run Code Online (Sandbox Code Playgroud)

任何人都可以建议从线程调用此函数时为什么抛出此异常?我敢肯定我会忽略一些基本而简单的东西.

谢谢,邓肯

Mar*_*ams 5

在您的Execute()方法中,您必须调用CoInitializeCoUnitialize设置和拆除COM库.

您的主线程在Application.Initialize()过程中自动执行此操作,但是,其他线程CoInitialize在调用COM函数之前需要调用.

确保你打电话CoInitializeExecute(),因为构造函数在父线程(通常是主线程)执行的方法,而不是在构造函数中.那不是你需要它的地方.必须从您计划进行COM调用的线程中调用它.

我建议使用这种格式:

try
  // OleCheck will raise an error if the call fails
  OleCheck(CoInitializeEx(NIL, COINIT_MULTITHREADED or COINIT_SPEED_OVER_MEMORY));
  try
    // Do work here
  finally
    CoUninitialize;
  end;
except
  // We failed, do something
end;
Run Code Online (Sandbox Code Playgroud)

这允许您在错误初始化时捕获错误并确保您调用CoUninitialize.