【发布时间】:2016-04-07 15:00:02
【问题描述】:
我们有一个 Windows 服务,它调用第 3 方方法,如果最终用户配置不当,该方法可能会挂起,这很难事先测试。我们通过超时调用任务中的方法来处理这种风险:
private int? FooWithTimeout()
{
var timeout = TimeSpan.FromMinutes(1);
var task = Task.Run(Foo);
if (!task.Wait(timeout))
{
Log("Foo timed out...");
return null;
}
if (task.IsFaulted)
{
Log("Foo threw an exception...");
return null;
}
return task.Result;
}
第 3 方方法永远阻塞等待来自无法响应的资源的输入。它不支持以任何方式、形状或形式取消,也没有内置超时。我们担心的是,随着服务的运行,这些任务会继续阻塞并慢慢积累,最终会消耗大量资源。
这是一个有效的担忧吗?我们是否需要以某种方式中止/处置任务?如果是这样,正确的做法是什么?
附录:有问题的第 3 方是 Crystal Reports。当被要求打印到需要用户进行某种额外输入的打印机时,它会挂起(例如,Microsoft XPS Document Writer 会在您打印到文件时提示您保存文件的位置)。挂起,我的意思是它试图显示一个用户提示来获取额外的输入,但它在 Windows 服务中,所以没有人看到用户提示,它永远等待人类告诉它如何打印。我们允许最终用户配置服务尝试打印到哪台打印机,并且实际上没有任何方法可以判断给定的打印机是否需要额外的输入而不是尝试打印。
【问题讨论】:
-
什么是
Foo?阻塞线程的正常方法?如果您需要中止任务,这可能会有所帮助:stackoverflow.com/a/19311606/1657476 -
您的问题基本上是“我依赖于执行不佳、随机挂起的第三方软件,我该怎么办?”在我看来,问题应该通过首先不这样做来解决。如果您的第三方在解决问题方面做得不好,请让他们修复他们糟糕的设计,或寻找替代方案。像杀死线程这样的危险解决方法似乎在过程中解决问题为时已晚。
-
哦-常见!我做了很多显示一些 UI 提示的 dll。当然它需要最终修复,但我并不总是有时间做正确的解决方案。然后一切顺利——注册表黑客、临时文件、批处理等等。这不是一个“糟糕的设计”,只是一个需要修复的错误。当您的应用程序很复杂时,很难找到所有出现的 UI 提示。