我必须使用API来调用第三方,理想情况下使用它返回的响应。 API具有内置的30秒超时,并且不允许您以编程方式设置该超时。我需要它在12秒内超时。这是我正在做的电话:
string response = theAPI.FunctionA(a,b,c,d);
我一直在想我可能需要使用异步调用来完成此操作并在12秒后中止线程。另一个stackoverflow问题似乎接近我正在考虑的问题:Implement C# Generic Timeout
......我只是想知道这是不是最好的方法。具体来说,我一直看到警告你无论如何都要调用EndInvoke的文章,我想知道参考示例中的Abort是否仍然会正确关闭该线程?我看到有一些评论非常关注使用Abort。
答案 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的其他用户。