【问题标题】:AutoResetEvent in Multi-threading多线程中的 AutoResetEvent
【发布时间】:2018-03-13 10:24:15
【问题描述】:

我在下面有一个示例代码,它创建了 多线程,在单独的线程中 lock 中有一个代码块。 如果响应为空或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 
            }
    }
 }

【问题讨论】:

    标签: c# multithreading autoresetevent


    【解决方案1】:

    我认为问题在于两个线程共享访问权限

    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 类重新开始。

    【讨论】:

    • 非常感谢您抽出宝贵的时间。首先,将尝试按照您的建议在线程本身内部使用超时,是的,您是 rite 第二个线程将花费 8 秒等待第一个实习生使超时提前达到。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-20
    • 1970-01-01
    相关资源
    最近更新 更多