c# - 如果花费的时间太长,则取消执行命令

标签 c# multithreading

我目前正在开发一款使用来自不同部门的程序集的软件。
我从这个程序集中调用一个方法,如下所示:

using (var connection = (IConnection) Factory.GetObject(typeof (IConnection)))

代码过去工作得很好。但是在最后几分钟,当我尝试启动我的程序时,它似乎什么也没做。调试时按暂停键显示它“卡在”了上面的行。
我猜他们只是在做一些维护或其他事情,但这不是这里的重点。
因此,如果程序未启动,我最好告诉用户出了什么问题。一些简单的东西,比如

MessageBox.Show("Could not connect", "Connection Error");

然后关闭程序。我的问题是:
如何在设定的时间后终止命令的执行并跳转到其他地方?
我的猜测是将它移动到一个单独的线程,然后让调用线程休眠一段时间几秒钟后,如果尚未完成,它会处理额外的线程。但这对我来说似乎真的很脏,必须有更好的方法。

最佳答案

您的问题可以分为两部分:

  1. 如何终止命令的执行?

唯一的办法就是中止线程。 但不要这样做。没有保证和安全的方法。 Thread.Interrupt 和 Thread.Abort 等方法可以唤醒线程。但只有当线程处于 WaitSleepJoin 状态并且它卡在托管代码中时它们才会工作。

看来你已经知道了。但是再一次,如果程序集内部的某些东西无限地挂起代码的执行,那么线程可能已经“消失”了。所以你是对的,该程序应该关闭。

  1. ...跳到别的地方?

好的方法是使用 TPL 和异步模型。 这是一个扩展方法,用于包装任何任务并在超时后过期。

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();
}

然后使用它

try
{
    using (var result = await Task.Run(() => (IConnection)Factory.GetObject(typeof(IConnection))).TimeoutAfter(1000))
    {
        ...
    }
}
catch (TimeoutException ex)
{
    //timeout
}

Here你可以找到更多信息

关于c# - 如果花费的时间太长,则取消执行命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34764279/

相关文章:

java - 对 Java 多线程网络应用程序进行单元测试

c# - 尝试停止 C# Windows 服务时拒绝访问

c# - .NETCore(Windows 8 框架)的 `GetCustomAttributes` 的等效方法是什么?

c# - 垃圾收集器是否调用 Dispose()?

C# xml 验证

android - thread.stop() 异常

python - 关于 fit_generator()/fit() 和线程安全

java - Netty,如何通过所有处理程序存储数据

c# - 从 FrameworkElementFactory 获取值

android - 如何使用通知和等待