如何处理不返回的函数

时间:2010-09-14 15:54:26

标签: c#

我有一个名为ApiCalls()的函数,它被包装在一个锁定器中,因为我使用的api不是多线程安全的。偶尔api调用无法返回,我想不出办法处理这种情况。我正在考虑在锁定对象上创建一个计时器,但似乎锁定器没有类似的东西。

4 个答案:

答案 0 :(得分:7)

这真的没有好的答案。一个糟糕但可能可行的答案是有一个监视程序线程在超时后中止调用线程。换句话说,在获得锁定之后但在调用API之前,你会命令看门狗杀死你。当你从电话回来时(如果你回来),你就会取消看门狗。

同样,这不是一个很好的解决方案,因为Abort非常混乱。

答案 1 :(得分:4)

我认为你不能合理地从这个问题中恢复过来。假设您可以超时,那么您将尝试再次调用API,但之前的调用仍处于活动状态,并且您已说过该API不是线程安全的。

你根本无法保护自己免受这种根本上有缺陷的依赖。

唯一真正安全的做法是重启过程。 Steven Sudit的建议是实现这一目标的一种方法。

答案 2 :(得分:3)

这可以通过将API调用包装在单独的程序集中并使用application domain类将该程序集加载到单独的AppDomain中来解决.....

  

使用应用程序域进行隔离   可能会导致流程失败的任务。   如果AppDomain的状态是那个   执行任务变得不稳定了   AppDomain可以在没有的情况下卸载   影响过程。这是   当进程必须运行时很重要   很长一段时间没有重新开始。

然后,您可以在单独的AppDomain中调用线程中止,向主机域发出中止已发生的信号。主机域将卸载违规域,从而卸载API,并启动API重置的新域。您还需要API域上的监视程序,以便主机可以在API域冻结时采取措施。

杂项链接:C# Nutshell AppDomain Listingscbrumme's WebLogGood example of use of AppDomainUsing AppDomain to Load and Unload Dynamic Assemblies

答案 3 :(得分:2)

唯一安全的解决方案可能是启动另一个进程来处理API调用,然后在它们卡住时终止进程。即使这样也不能保证API的处理程序不会进入只能通过系统重启来治愈的虚假状态,但是使用Thread.Abort可能会导致进程崩溃。

如果你不想使用“不信任”的方法来杀死进程,你可以在进程中有一个线程执行API调用,而另一个线程则监视“请死”消息。看门狗可能很棘手;如果看门狗设置为15秒并且操作需要17秒才能完成,则可以请求操作,15秒后超时,重试操作,15秒后超时等等。无限期。在每次失败后调整看门狗时间可能会很好(例如尝试一个动作,让它最多有15秒;如果这不起作用,没有人在抱怨,再试一次,让它走30秒;如果那仍然是没有好处,给它60秒。)