none
跪求高手解答WaitHandle.WaitOne的第二参数! RRS feed

答案

  • 上面的帖子写的很清楚了,我再追加一句。看 MSDN:

    The exitContext parameter has no effect unless the WaitOne method is called from inside a nondefault managed context. This can happen if your thread is inside a call to an instance of a class derived from ContextBoundObject. Even if you are currently executing a method on a class that does not derive from ContextBoundObject, like String, you can be in a nondefault context if a ContextBoundObject is on your stack in the current application domain.

    When your code is executing in a nondefault context, specifying true for exitContext causes the thread to exit the nondefault managed context (that is, to transition to the default context) before executing the WaitOne method. The thread returns to the original nondefault context after the call to the WaitOne method completes.

    This can be useful when the context-bound class has SynchronizationAttribute. In that case, all calls to members of the class are automatically synchronized, and the synchronization domain is the entire body of code for the class. If code in the call stack of a member calls the WaitOne method and specifies true for exitContext, the thread exits the synchronization domain, allowing a thread that is blocked on a call to any member of the object to proceed. When the WaitOne method returns, the thread that made the call must wait to reenter the synchronization domain.

    也就是说,当调用代码在一个可能访问从 ContextBoundObject 派生的类型实例时,这个参数才有作用。对于其他默认的 Context,该参数无效。


    Mark Zhou
    2010年11月25日 10:37

全部回复

  • 上面的帖子写的很清楚了,我再追加一句。看 MSDN:

    The exitContext parameter has no effect unless the WaitOne method is called from inside a nondefault managed context. This can happen if your thread is inside a call to an instance of a class derived from ContextBoundObject. Even if you are currently executing a method on a class that does not derive from ContextBoundObject, like String, you can be in a nondefault context if a ContextBoundObject is on your stack in the current application domain.

    When your code is executing in a nondefault context, specifying true for exitContext causes the thread to exit the nondefault managed context (that is, to transition to the default context) before executing the WaitOne method. The thread returns to the original nondefault context after the call to the WaitOne method completes.

    This can be useful when the context-bound class has SynchronizationAttribute. In that case, all calls to members of the class are automatically synchronized, and the synchronization domain is the entire body of code for the class. If code in the call stack of a member calls the WaitOne method and specifies true for exitContext, the thread exits the synchronization domain, allowing a thread that is blocked on a call to any member of the object to proceed. When the WaitOne method returns, the thread that made the call must wait to reenter the synchronization domain.

    也就是说,当调用代码在一个可能访问从 ContextBoundObject 派生的类型实例时,这个参数才有作用。对于其他默认的 Context,该参数无效。


    Mark Zhou
    2010年11月25日 10:37
  • 帖子里那个MyCounter,我这样访问会发生死锁,不知为何?

           

    namespace ConsoleApplication4
    {
      using System;
      using System.Threading;
    
      [Synchronization]
      public class MyCounter : ContextBoundObject
      {
    
        private int _expectedCounterVal;
        private int _currentCounterVal;
        private ManualResetEvent _event = new ManualResetEvent(false);
    
        public void WaitUntilCounterIs(int counterVal)
        {
          _expectedCounterVal = counterVal;
          _event.WaitOne(TimeSpan.FromDays(1), true);
        }
    
        public void IncrementCounter()
        {
          if (++_currentCounterVal >= _expectedCounterVal)
          {
            _event.Set();
          }
        }
     
    
        static void Main()
        {
          MyCounter counter = new MyCounter();
          Output("Main starting.");
          ThreadPool.QueueUserWorkItem(new WaitCallback(WorkThreadAddCounter), counter);
          counter.WaitUntilCounterIs(10);
          Output("Main ending.");
        }
    
        static void WorkThreadAddCounter(object counter)
        {
          Output("Work starting.");
          for (int i = 0; i < 20; i++)
          {
            Thread.Sleep(10);
            ((MyCounter)counter).IncrementCounter();
            Output(i.ToString());
          }
          Output("Work ending.");
        }
    
        static void Output(string text)
        {
          Console.WriteLine(DateTime.Now.ToString("HH:mm:ss ") + text);
        }
      }
    
    
    }
    
    2010年11月30日 3:11