【问题标题】:Manually Timing out a C# Thread手动使 C# 线程超时
【发布时间】:2011-01-12 07:49:06
【问题描述】:

我需要为长时间运行的线程添加超时。我们遇到了一些外部问题,这些问题有时会导致该线程无限期地挂在某行代码上。为了使我们的进程更加健壮,我们想检测线程不再主动运行/轮询并中止线程。这将让我们清理资源并重新启动线程。

添加此功能的首选方法是什么?

【问题讨论】:

    标签: c# multithreading timeout


    【解决方案1】:

    首选方法是在它自己的进程中运行不可靠的子系统,而不是在它自己的线程中运行。这样,当它表现不佳时,您可以破坏整个过程并让操作系统清理它留下的任何可怕的混乱。杀死在你的进程中运行不可靠代码的线程会对你的代码产生各种讨厌的副作用,因为操作系统无法知道哪些资源属于行为不端的线程以及你仍在使用哪些资源。

    长话短说:不要与无法控制的代码共享进程。

    【讨论】:

    • 这对我来说不太可行,因为我需要从这个过程中得到一个结果(它是 IBM MQSeries 客户端)。因此,这会使这个单独的过程难以将数据返回到我的应用程序。
    • @Joel:那么你必须决定你喜欢什么:健壮和笨重,或者脆弱和容易。设计当然是做出妥协以最好地为您的客户和利益相关者服务的艺术。您的客户和利益相关者认为产品的稳健性高于还是低于编写产品的难易程度?
    • +1 用于单独的进程,尽管我的回答。 @Joel,您为什么不让最后一次民意调查将结果传达给您的监控进程(在结束进程之前)?对于进程间通信,我假设您将使用 XML-RPC 或其他东西。让可疑进程成为“奴隶”。
    【解决方案2】:

    你需要两件事:

    1. 可以执行监控和中止的其他线程(您的“监控”线程)
    2. 查看可疑线程是否仍在工作的某种机制

    在最简单的版本中,您的可疑线程以可靠的频率使用当前时间更新共享静态变量。如何适应你的线程的控制流取决于你(这是困难的部分——你通常会用另一个线程来做那种事情)。然后只需唤醒第二个线程并经常检查它。如果不是最近的时间,请中止线程。

    //suspect thread
    foreach(var thing in whatever)
    {
        //do some stuff
        SomeClass.StaticVariable = DateTime.Now;
    }
    
    //monitor thread
    while(shouldStillBeWorking)
    {
        Thread.Sleep(TimeSpan.FromMinutes(10));
        if (DateTime.Now.Subtract(TimeSpan.FromMinutes(15) < SomeClass.StaticVariable)
            suspectThread.Abort()
    }
    

    【讨论】:

    • 这符合我想要解决问题的方式。很高兴看到它被其他人验证。虽然我可以欣赏 Eric 的回应,但它根本不适合我的特定应用程序。谢谢大家!
    【解决方案3】:

    在您的主应用程序中启动一个计时器,在您的超时时间过去后中止工作线程。使用工作线程中的回调方法来重置计时器。

    【讨论】:

      猜你喜欢
      • 2010-11-20
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      • 2011-01-17
      • 2017-04-24
      相关资源
      最近更新 更多