繁体   English   中英

在C#中唤醒线程

[英]Waking a thread in C#

我正在寻找一种使线程进入睡眠状态并将其唤醒的简单方法。 该线程在无限循环中在后台运行,有时会执行一些工作,有时会一直运行。 我发现没有与Sleep()相对应的Wait(),并且使用Interrupt()唤醒线程会导致异常。 显然,睡眠线程并不意味着被打扰。
因为我知道工作何时出现,所以告诉线程似乎是个好主意,而不是一遍又一遍地检查它。

如何将线程置于“较轻的睡眠”状态,以便能够每秒单独唤醒或在其他线程的命令下唤醒?

//Thread to put to sleep and wake (thread1)
while (true)
{
    if (thereIsWork)
    { DoWork(); }
    //put thread to sleep in a way that other threads can wake it, and it wakes alone after some time (eg. 1000 ms)
    // Thread.Sleep(1000); //nice, but not working as desired
}

--

//Other thread:

thereIsWork = true;
//thread1.Wake(); //Not existing

线程不应进入Sleep() ,而应在AutoResetEventManualResetEvent上调用WaitOne() ,直到其他线程在同一resetevent对象上调用Set()为止。

您可以为此使用AutoResetEvent只需调用Set()即可表明需要完成工作,并让线程等待使用WaitOne()它。

这意味着以这种方式进行通信的线程共享相同的AutoResetEvent实例-您可以将其作为执行实际工作的线程的依赖项传递。

如何通过Monitor Pulse和Wait使用阻塞队列:

class BlockingQueue<T>
{
    private Queue<T> _queue = new Queue<T>();
    public void Enqueue(T data)
    {
        if (data == null) throw new ArgumentNullException("data");
        lock (_queue)
        {
            _queue.Enqueue(data);
            Monitor.Pulse(_queue);
        }
    }
    public T Dequeue()
    {
        lock (_queue)
        {
            while (_queue.Count == 0) Monitor.Wait(_queue);
            return _queue.Dequeue();
        }
    }
}

然后线程1变成

BlockingQueue<Action> _workQueue = new BlockingQueue<Action>();

while (true)
{
    var workItem = _workQueue.Dequeue();
    workItem();
}

而另一个线程:

_workQueue.Enqueue(DoWork);

注意:如果您使用的是.Net 4 BlockingCollection ,而不是Enqueue和Dequeue,则应使用内置类型。

编辑:好的。 如果您真的想简单...

//Thread to put to sleep and wake (thread1)
while (true)
{
    lock(_lock)
    {
        while (!thereIsWork) Monitor.Wait(_lock);
        DoWork(); 
    }
    //put thread to sleep in a way that other threads can wake it, and it wakes alone after some time (eg. 1000 ms)
    // Thread.Sleep(1000); //nice, but not working as desired
}

//Other thread:
lock(_lock)
{
    thereIsWork = true;
    //thread1.Wake(); //Not existing
    Monitor.Pulse(_lock);
}

我不是线程专家,但是EventWaitHandle可能正是您想要的。 检查此链接

暂无
暂无

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

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