簡體   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