临时暂停工作线程的正确方法

时间:2012-04-06 18:24:42

标签: c# .net multithreading sleep worker

我有一个工作线程,可能会在短时间内处于活动状态并在其余时间闲置。我想让线程进入睡眠状态,然后在需要时将其唤醒。

我应该注意的任何其他建议吗?

谢谢!

  • 这是在C#/。NET4

3 个答案:

答案 0 :(得分:4)

您可能不应该使用持久性工作线程 - 使用线程池。这正是它的目的。

ThreadPool.QueueUserWorkItem(() => {
    // My temporary work here
});

如果您坚持使用持久性工作线程,请将其运行:

// This is our latch- we can use this to "let the thread out of the gate"
AutoResetEvent threadLatch = new AutoResetEvent(false);

// The thread runs this
public void DoBackgroundWork() {
    // Making sure that the thread is a background thread
    // ensures that the endless loop below doesn't prevent
    // the program from exiting
    Thread.IsBackground = true;
    while (true) {

        // The worker thread will get here and then block 
        // until someone Set()s the latch:
        threadLatch.WaitOne();

        // Do your work here
    }
}

//  To signal the thread to start:
threadLatch.Set();

另请注意,如果此后台线程将完全与用户界面交互,则需要相应地调用Invoke或BeginInvoke。见http://weblogs.asp.net/justin_rogers/pages/126345.aspx

答案 1 :(得分:2)

只需使用一个事件来暂停工作线程:重置 - 暂停,设置 - 取消暂停(工作)状态。

以下是演示该方法的草稿版本的代码。

class Worker
{
    private Thread _thread;

    // Un-paused by default.
    private ManualResetEvent _notToBePaused = new ManualResetEvent(true);

    public Worker()
    {
        _thread = new Thread(Run)
            {
                IsBackground = true
            };
    }

    /// <summary>
    /// Thread function.
    /// </summary>
    private void Run()
    {
        while (true)
        {
            // Would block if paused!
            _notToBePaused.WaitOne();

            // Process some stuff here.
        }
    }

    public void Start()
    {
        _thread.Start();
    }

    public void Pause()
    {
        _notToBePaused.Reset();
    }

    public void UnPause()
    {
        _notToBePaused.Set();
    }
}

答案 2 :(得分:1)

使用WaitHandle发信号是正确的方法,但只是添加其他人已经说过的话

我通常会同时使用2个信号,否则你不知道在需要时是“继续”还是“退出” - 或者不得不采用不那么优雅的方式(停止线程 - 当然还有其他方法可以做这样的事情,只是一个'模式')。因此,通常它与“退出”信号和“新工作可用”信号一起工作 - 一致工作。例如

WaitHandle[] eventArray = new WaitHandle[2] { _exitEvent, _newWorkEvent };
while ((waitid = WaitHandle.WaitAny(eventArray, timeout, false)) > 1)
{
    // do your work, and optionally handle timeout etc.
}

请注意:
退出ManualResetEvent,初始状态为'false' - 退出时设置'Set'事件 _newWorkManual,在这种情况下,你需要暂停/继续从外面这是你​​想要的 - 我想 - ......或者也可能是new AutoResetEvent(false),你发出“信号”做一个循环的工作,信号立即返回'假' - 你需要为每个'新批'的工作重复这一点 - 这是有点简化。 (通常与传递的某些“消息”并行,当然以某种方式同步)。

希望这会增加更多信息,

相关问题