Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Web services 从线程调用远程SOAP调用时发生异常_Web Services_Multithreading_Delphi_Soap - Fatal编程技术网

Web services 从线程调用远程SOAP调用时发生异常

Web services 从线程调用远程SOAP调用时发生异常,web-services,multithreading,delphi,soap,Web Services,Multithreading,Delphi,Soap,这是我几分钟前提出的问题的扩展/下一步 我有一个带有主窗体和线程的Delphi应用程序。线程每X秒向远程对象发出一个web服务请求。然后,它将发回主窗体,主窗体处理用新信息更新UI的操作 我以前在线程中使用了TTimer对象,当TTimer回调函数运行时,它在主线程的上下文中运行(但远程web服务请求确实起作用)。这完全违背了单独线程的目的,因此我现在在线程的Execute函数中有了一个简单的循环和睡眠例程。问题是,从GetIMySOAPService()返回时引发异常 有人能告诉我们为什么从线

这是我几分钟前提出的问题的扩展/下一步

我有一个带有主窗体和线程的Delphi应用程序。线程每X秒向远程对象发出一个web服务请求。然后,它将发回主窗体,主窗体处理用新信息更新UI的操作

我以前在线程中使用了TTimer对象,当TTimer回调函数运行时,它在主线程的上下文中运行(但远程web服务请求确实起作用)。这完全违背了单独线程的目的,因此我现在在线程的Execute函数中有了一个简单的循环和睡眠例程。问题是,从GetIMySOAPService()返回时引发异常

有人能告诉我们为什么从线程调用这个函数时会抛出这个异常吗?我肯定我忽略了一些基本和简单的东西


谢谢,Duncan,为了我未来的自我…我需要在我的Execute方法中进行联合初始化和联合初始化:

procedure TPollingThread.Execute;
begin

  CoInitialize(nil);

  while not Terminated  do
  begin
  // ...
  end;


   CoUnInitialize;
end;
Execute()
方法中,必须调用
CoInitialize
CoInitialize
来设置并拆除COM库

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

确保在
Execute()
方法中调用
CoInitialize
,而不是在构造函数中,因为构造函数是在父线程(通常是主线程)中执行的。那不是你需要的地方。它必须从您计划从中进行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;

这允许您在初始化失败时捕获错误,并确保您调用
coninitialize

您也应该发布异常类和消息。异常类为EOleException,消息为“尚未调用协同初始化”。。。这解决了我的问题,因为我认为XML引擎将需要它。执行任何与OLE相关的操作都需要调用
CoInitialize()
。在OLE单元的初始化过程中,主VCL线程自己执行,对于程序员必须执行的所有其他线程,这并不直接相关,但我看到的另一个问题是,在发出终止线程的信号后,很可能会触发另一个SOAP请求。依我看,如果终止是真的,那么你不应该执行任何冗长的操作。您可以将睡眠(5000)移动到循环的底部,或者您可以使用“如果未终止,请尝试”来保护“尝试”。@Chris:True,但这仍会阻止程序终止长达5秒。简单的解决方法是在循环中调用
Sleep(100)
或类似函数,并在每次迭代中检查
Terminated
。另一种方法是调用
SleepEx()
并在线程需要终止时将APC()排队。我还建议您阅读错误消息。它们可能包含隐藏的提示:)+1用于仅在
coInitializeX()
成功时调用
counInitializeX()
,以及在thread.mghie中有顶级异常处理程序,我知道我的应用程序中有一个不匹配的Co/CoUn,因为我在其中抛出了CoInitialize,因为错误就是这么说的。。。。我会在第一时间修复,但这通常是一个变更请求或升级的bug。与此同时,我将面对什么样的问题?内存泄漏,或者它会以某种方式崩溃,还是仅仅是良性的?@Chris:我不确定,我希望它是良性的,可能是一些窗口和句柄没有正确释放。尽管如此,我还是喜欢投票支持促进良好实践的答案,文档()明确指出,需要平衡调用才能优雅地关闭COM库。谢谢mghie,我会在方便的时候尽早修复,很高兴知道这可能不是太严重。
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;