我目前正在开发一个使用不同部门的程序集的软件。
我从这样的程序集中调用方法:
using (var connection = (IConnection) Factory.GetObject(typeof (IConnection)))
Run Code Online (Sandbox Code Playgroud)
该代码过去可以正常工作。但是在最后几分钟,当我尝试启动它时,我的程序似乎无能为力。在调试时按暂停显示我在上面的行中被“卡住了”。
我的猜测是他们只是在做一些维护或其他事情,但这不是重点。
因此,我很高兴告诉用户如果程序无法启动又出了什么问题。简单的东西
MessageBox.Show("Could not connect", "Connection Error");
Run Code Online (Sandbox Code Playgroud)
然后关闭程序。我的问题是:
如何在设定的时间后终止命令的执行并跳到其他地方?
我的猜测是将其移动到单独的线程中,然后将调用线程置于休眠状态几秒钟,之后,如果尚未完成,它将处理多余的线程。但这对我来说确实很脏,必须有一种更好的方法。
您的问题可以分为两部分:
唯一的方法是中止线程。但是不要这样。没有保证和安全的方法。诸如Thread.Interrupt和Thread.Abort之类的方法可以唤醒线程。但是,仅当线程处于WaitSleepJoin状态并且挂在托管代码中时,它们才起作用。
好像您已经知道了。但是再一次,如果程序集内的某些内容无限地挂起了代码的执行,则线程可能已“消失”。因此,您应该关闭该程序是正确的。
好的方法是使用TPL和异步模型。这是一种扩展方法,用于包装任何Task并在超时后到期。
public static async Task TimeoutAfter(this Task task, int millisecondsTimeout)
{
if (task == await Task.WhenAny(task, Task.Delay(millisecondsTimeout)))
await task;
else
throw new TimeoutException();
}
Run Code Online (Sandbox Code Playgroud)
然后用
try
{
using (var result = await Task.Run(() => (IConnection)Factory.GetObject(typeof(IConnection))).TimeoutAfter(1000))
{
...
}
}
catch (TimeoutException ex)
{
//timeout
}
Run Code Online (Sandbox Code Playgroud)
在这里您可以找到更多信息