简体   繁体   English

手动定时C#线程

[英]Manually Timing out a C# Thread

I have a need to add a timeout to a long running thread. 我需要为长时间运行的线程添加超时。 We're having some external issues which can sometimes cause that thread to hang at a certain line of code indefinitely. 我们遇到了一些外部问题,这些问题有时会导致该线程无限期地挂在某一行代码上。 To make our process more robust, we would like to detect that the thread is no longer actively running/polling and abort the thread. 为了使我们的进程更健壮,我们希望检测到线程不再主动运行/轮询并中止线程。 This would let us clean up the resources and restart the thread. 这将让我们清理资源并重新启动线程。

What would be the preferred method of adding this functionality? 添加此功能的首选方法是什么?

The preferred method is to run the unreliable subsystem in its own process , not its own thread . 首选方法是在其自己的进程中运行不可靠的子系统,而不是自己的线程 That way when it behaves badly you can destroy the entire process and have the operating system clean up whatever horrid mess it leaves behind. 这样,当它表现得很糟糕时,你可以破坏整个过程并让操作系统清理它留下的任何可怕的混乱。 Killing a thread that is running unreliable code in your process can have all kinds of nasty side effects on your code because the operating system has no way of knowing what resources belong to the ill-behaved thread and which ones you're still using. 杀死在您的进程中运行不可靠代码的线程可能会对您的代码产生各种令人讨厌的副作用,因为操作系统无法知道哪些资源属于不良行为的线程以及您仍在使用哪些资源。

Long story short: do not share a process with code you cannot control. 简而言之: 不要与无法控制的代码共享流程。

You need two things: 你需要两件事:

  1. Some other thread that can do the monitoring and abort (your "monitor" thread) 一些其他可以进行监视和中止的线程(你的“监视器”线程)
  2. Some mechanism to see if the suspect thread is still working 一些机制,以查看可疑线程是否仍在工作

In the simplest version your suspect thread updates a shared static variable with the current time with a reliable frequency. 在最简单的版本中,您的可疑线程以可靠的频率更新当前时间的共享静态变量。 How that fits into the control flow of your thread is up to you (This is the hard part - you would normally do that sort of thing with, ahem, another thread). 如何适应你的线程的控制流程取决于你(这是困难的部分 - 你通常会做这样的事情,咳咳,另一个线程)。 Then just have a second thread wake up and check it every so often. 然后只需要唤醒第二个线程并经常检查它。 If it's not a recent time, abort the thread. 如果不是最近的时间,则中止线程。

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

Start a timer in your main app that aborts the worker thread after your timeout period elapses. 在主应用程序中启动计时器,在超时时间结束后中止工作线程。 Use a callback method from your worker thread to reset the timer. 使用工作线程中的回调方法重置计时器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM