我怎么能施加自己的超时?

时间:2009-02-10 17:28:14

标签: multithreading timeout abort

我必须使用API​​来调用第三方,理想情况下使用它返回的响应。 API具有内置的30秒超时,并且不允许您以编程方式设置该超时。我需要它在12秒内超时。这是我正在做的电话:

string response = theAPI.FunctionA(a,b,c,d);

我一直在想我可能需要使用异步调用来完成此操作并在12秒后中止线程。另一个stackoverflow问题似乎接近我正在考虑的问题:Implement C# Generic Timeout

......我只是想知道这是不是最好的方法。具体来说,我一直看到警告你无论如何都要调用EndInvoke的文章,我想知道参考示例中的Abort是否仍然会正确关闭该线程?我看到有一些评论非常关注使用Abort。

2 个答案:

答案 0 :(得分:4)

中止线程通常是一个坏主意。为什么不让呼叫完成(或在30秒后超时)但忽略结果(并继续),如果它需要超过12秒?

答案 1 :(得分:2)

当然,

Thread.Abort会关闭该主题,因为它会调用Win32 TerminateThread

此操作的结果将取决于您API喜欢TerminateThread关闭的方式。

如果您的方法被称为NuclearPlant.MoveRod()Defibrillator.Shock(),我宁愿等待这30秒。

这种方法没有让受害者做一些清理的机会:

  

TerminateThread用于导致线程退出。发生这种情况时,目标线程无法执行任何用户模式代码。附加到线程的DLL不会通知线程正在终止。系统释放线程的初始堆栈。

MSDN中所述:

  

TerminateThread是一种危险的功能,只能在最极端的情况下使用。仅当您确切知道目标线程正在执行的操作时,才应调用TerminateThread,并且您可以控制目标线程在终止时可能正在运行的所有代码。例如,TerminateThread可能会导致以下问题:

     
      
  • 如果目标线程拥有临界区,则不会释放临界区。
  •   
  • 如果目标线程正在从堆中分配内存,则不会释放堆锁。
  •   
  • 如果目标线程在终止时正在执行某些kernel32调用,则线程进程的kernel32状态可能不一致。
  •   
  • 如果目标线程正在操纵共享DLL的全局状态,则DLL的状态可能会被破坏,从而影响DLL的其他用户。
  •