C#:监控 - 等待,脉搏,PulseAll [英] C# : Monitor - Wait,Pulse,PulseAll

查看:217
本文介绍了C#:监控 - 等待,脉搏,PulseAll的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有理解等待()很难脉冲() PulseAll()。将所有的人都避免死锁?我想AP preciate如果你解释如何使用他们?

I am having hard time in understanding Wait(), Pulse(), PulseAll(). Will all of them avoid deadlock? I would appreciate if you explain how to use them?

推荐答案

短版:

lock(obj) {...}

短手为 Monitor.Enter / Monitor.Exit (有异常处理等)。如果没有其他人有锁,你可以得到它(并运行code) - 否则你的线程被阻塞,直到锁被获得性(由另一个线程释放它)

is short-hand for Monitor.Enter / Monitor.Exit (with exception handling etc). If nobody else has the lock, you can get it (and run your code) - otherwise your thread is blocked until the lock is aquired (by another thread releasing it).

死锁通常发生在两种答:两个线程以不同的顺序锁定的东西:

Deadlock typically happens when either A: two threads lock things in different orders:

thread 1: lock(objA) { lock (objB) { ... } }
thread 2: lock(objB) { lock (objA) { ... } }

(在这里,如果他们每个人获得的第一个锁,也不能的曾经的拿到第二,因为没有线程可以退出来释放自己的锁)

(here, if they each acquire the first lock, neither can ever get the second, since neither thread can exit to release their lock)

此情况,可以通过以相同的顺序始终锁定被最小化;你可以使用恢复(在一定程度上) Monitor.TryEnter (而不是 Monitor.Enter / 锁定),并指定超时。

This scenario can be minimised by always locking in the same order; and you can recover (to a degree) by using Monitor.TryEnter (instead of Monitor.Enter/lock) and specifying a timeout.

或B:您可以阻止自己的东西一样的WinForms当线程切换,同时保持一个锁:

or B: you can block yourself with things like winforms when thread-switching while holding a lock:

lock(obj) { // on worker
    this.Invoke((MethodInvoker) delegate { // switch to UI
        lock(obj) { // oopsiee!
            ...
        }
    });
}

僵局出现明显之上,但是当你有面条code也不是那么明显;可能的答案:不线程开关,同时持有锁,或使用的BeginInvoke ,这样你至少可以退出锁(让UI播放)

The deadlock appears obvious above, but it isn't so obvious when you have spaghetti code; possible answers: don't thread-switch while holding locks, or use BeginInvoke so that you can at least exit the lock (letting the UI play).


等待 / 脉冲 / PulseAll 是不同的;它们是用于信令。我用这个在这个答案信号,因此:

Wait/Pulse/PulseAll are different; they are for signalling. I use this in this answer to signal so that:


  • 出列:如果您尝试在队列为空出列数据,它等待另一个线程来添加数据,这会唤醒阻塞的线程

  • 排队:如果你试图排队数据时队列已满,它等待另一个线程删除数据,这唤醒阻塞的线程

  • Dequeue: if you try to dequeue data when the queue is empty, it waits for another thread to add data, which wakes up the blocked thread
  • Enqueue: if you try and enqueue data when the queue is full, it waits for another thread to remove data, which wakes up the blocked thread

脉冲只醒来的有一个的话题 - 但我不是足够聪明来证明下一个线程始终是一个我想要的,所以我倾向于使用 PulseAll ,并简单地重新验证,然后再继续的条件;作为一个例子:

Pulse only wakes up one thread - but I'm not brainy enough to prove that the next thread is always the one I want, so I tend to use PulseAll, and simply re-verify the conditions before continuing; as an example:

        while (queue.Count >= maxSize)
        {
            Monitor.Wait(queue);
        }

通过这种方法,我可以放心地加入脉冲,其他的含义没有我的存在code假设我醒过来,因此没有数据 - 这为方便的时候(在相同的例子),我以后需要添加一个关闭()方法。

With this approach, I can safely add other meanings of Pulse, without my existing code assuming that "I woke up, therefore there is data" - which is handy when (in the same example) I later needed to add a Close() method.

这篇关于C#:监控 - 等待,脉搏,PulseAll的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆