0

我必须使用 API 来调用第三方,并且最好使用它返回的响应。API 有一个内置的 30 秒超时,并且不允许您以编程方式设置它。我需要它在 12 秒内超时。这是我正在打的电话:

字符串响应 = theAPI.FunctionA(a, b, c, d);

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

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

4

2 回答 2

4

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

于 2009-02-10T17:30:14.137 回答
2

Thread.Abort当然会关闭线程,因为它会调用 Win32 TerminateThread

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

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

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

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

如中所述MSDN

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

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