簡體   English   中英

AutoResetEvent和ManualResetEvent之間的混合

[英]Hybrid between AutoResetEvent and ManualResetEvent

我想知道是否有任何混合EventWaitHandle會在調用.Set()時像AutoResetEvent一樣自動重置其狀態,同時允許每個執行.WaitOne()的人都像ManualResetEvent一樣傳遞。

我提出的唯一解決方案是使用ManualResetEvent並進行以下操作的非常丑陋的解決方案:

event.Set();
Thread.Sleep(100);
event.Reset();

什么是更好的方法呢? 謝謝。

UPD:謝謝漢斯,我想出了以下解決方案。 看起來很有效:

class HybridWaitHandle
{

    private bool signal = false;
    private readonly object locker = new object();
    private int blocked = 0;

    void WaitOne()
    {
        lock (locker)
        {
            blocked++;

            while (!signal) Monitor.Wait(locker);

            blocked--;

            if (blocked == 0)
                signal = false;
        }
    }

    void Set()
    {
        lock (locker)
        {
            signal = true;
            Monitor.PulseAll(locker);
        }
    }

}

使用Monitor.PulseAll()代替。 示例代碼在此處被稱為“綁定緩沖區”。 在.NET 4中以BlockingCollection <>的形式提供。

在不了解您如何使用它的情況下很難說,但這聽起來像一個信號量可能很好地解決了這個問題。 您釋放信號量N次。 這樣就可以運行N個線程。 釋放N個線程后,將重置信號燈。 請注意,從技術上講,這不一定是N個單獨的線程-它可以是1個線程釋放N次。

這樣,如果您需要/想要確保要釋放N個單獨的線程,則可能(為了一種可能)想要創建2個單獨的信號量,在過程的連續步驟中在兩個信號量之間交替。 N個線程等待第一個信號量。 釋放N次后,每個線程都會運行,然后等待另一個信號量。 最終所有線程將被第一個信號量釋放並運行,這將重置該信號量。

然后,您可以使用其他信號量執行下一個處理步驟。

但是請注意,這與線程趨於最佳工作的方式有些相反。 您正在強迫所有線程保持同步,但是如果您讓它們盡可能“自由”運行,它們通常處於最佳狀態。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM