簡體   English   中英

EventWaitHandle.Set,等待超時和釋放線程數

[英]EventWaitHandle.Set, wait timeout and number of released threads

來自文檔( EventWaitHandle.Set

不能保證每次調用 Set 方法都會從重置模式為 EventResetMode.AutoReset 的 EventWaitHandle 中釋放線程。 如果兩個調用靠得太近,以至於第二個調用發生在一個線程被釋放之前,那么只有一個線程被釋放。 就好像第二次通話沒有發生一樣。 此外,如果在沒有線程等待且 EventWaitHandle 已發出信號時調用 Set,則該調用無效。

考慮以下代碼

private AutoResetEvent _are = new AutoResetEvent(false);

private void AnyMethod()
{
  await _are.Set();
}

情況1

private async Task Method1(long timeout)
{  
  await _are.WaitOneAsync(timeout);
}

private async Task Method2()
{  
  await _are.WaitOneAsync();
}

private static Task WaitOneAsync(this WaitHandle waitHandle, long timeout)
{
    if (waitHandle == null)
        throw new ArgumentNullException("waitHandle");

    var tcs = new TaskCompletionSource<bool>();
    var rwh = ThreadPool.RegisterWaitForSingleObject(waitHandle,
        delegate { tcs.TrySetResult(true); }, null, timeout, true);
    var t = tcs.Task;
    t.ContinueWith( (antecedent) => rwh.Unregister(null));
    return t;
}

案例二


private void Method1(int timeout)
{  
  _are.WaitOne(timeout);
}

private void Method2()
{  
  _are.WaitOne();
}

想象一下, Method1Method2都被調用,然后AnyMethodMethod1超時時及時釋放一個線程。

在情況 1 和 2 中是否有關於線程釋放的保證,或者Set方法行為通常適用於任何一個線程釋放靠近另一個發生時的任何線程釋放?

從醫生...

文檔引用描述了調用Set並且沒有線程等待時會發生什么。 您問題的 rest 中的代碼都是關於在線程等待時調用Set的,因此該文檔的段落不適用。

在情況 1 和 2 中是否有關於線程釋放的保證,或者 Set 方法行為通常適用於任何線程釋放,當兩者靠近另一個時?

是的; 等待線程之一將被釋放。 如果事件在超時之前Set ,它可能是任一線程; 如果事件在超時后Set ,它將是沒有超時的線程。

暫無
暫無

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

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