簡體   English   中英

多線程中的AutoResetEvent

[英]AutoResetEvent in Multi-threading

我下面有一個示例代碼,該示例代碼創建了多線程,並在單獨的線程中的lock內包含了一塊代碼。 如果響應為null或autoReset.WaitOne(timeout)經過了時間跨度,那么我將中止子線程,以便允許隊列中的下一個等待線程進入lock並執行操作。 但是這里的問題是,如果說ThreadA需要8秒鍾來執行lock的復雜代碼,那么下一個等待線程說ThreadB僅剩下2秒(因為所有線程同時啟動AutoResetEvent's等待時間)。

我如何使每個線程具有相同的時間跨度來執行復雜的代碼塊。 我現在正嘗試解決過去2天的問題,任何輸入都會非常有幫助。

Class A
{
    static void Main(){
     for(int i=0; i < 2; i++)
      {
        var mainThread = new Thread(ParentThreadMethod);
        mainThread.Start();
      }
    }

    void ParentThreadMethod(){
      var autoReset = new AutoResetEvent(false);
      ClassB obj;
      var childThread = new Thread(() =>
        {
            obj = new ClassB();
            var result = obj.ChildThreadMethod();
            autoReset.Set();
        }       
         childThread.Start();

         // wait for 10sec
         autoReset.WaitOne(10000);           
    }
 } 

 Class B
 {
    private static readonly object threadLock = new object();
    string ChildThreadMethod(){
     lock (threadLock)
            {
                // complex logic taking 8sec 
            }
    }
 }

我認為問題在於兩個線程共享對

private static readonly object threadLock = new object();

這意味着第二個線程將花費8秒等待第一個線程退出關鍵區域。 這使超時看起來快到了。 但是超時工作正常。

看來您只想在成功輸入鎖定后才開始超時。 這意味着線程本身必須啟動超時,因為只有子線程知道何時進入鎖。

它可能看起來像這樣:

lock (threadLock) {
    var timeoutTask = Task.Delay(10000);
    var workTask = Task.Run(RunWork);
    var firstTask = Task.WhenAny(timeoutTask, workTask).Result;

    if (!workTask.IsCompleted) {
     AbortWork();
     workTask.Wait(); //Wait for cancellation to finish.
    }
}

通常,較新的TPL功能比線程和事件等更易於使用。如果此代碼是新代碼,我將從TPL類開始。

暫無
暫無

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

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