private void OutPutEven(object lst)  
        {  
            AutoResetEvent ateA = (lst as List<AutoResetEvent>)[0];  
            AutoResetEvent ateB = (lst as List<AutoResetEvent>)[1];  
  
            for (int i = 0; i < 100; i += 2)  
            {  
                //设置本线程为无信号  
                ateA.WaitOne();  
                Console.WriteLine(i);                   
                ateB.Set();  //设置输出奇数线程有信号                 
            }  
        }  上面代码是一个线程执行的方法,我没有写完全代码,太多了
我想问,WaitOne方法Set方法是什么意思啊,MSDN上得解释很咬口
设置本线程为无信号?设置线程有信号 ?什么意思哦?

解决方案 »

  1.   

    WaitOne 和 Set 属于一对方法。假设 AutoResetEvent 初始化为 true,就是已经占用了一个信号。
    那么在 Set(释放信号) 方法没有被调用前,
    WaitOne 会一直等到该信号量被释放
    (如果成功获得信号则返回true,
     如果超时或者失败则返回false,WaitOne还可以传入参数设置等待超时时间)应该还有一个方法是对 ateA.Set(); 
      

  2.   

    上面代码是不是写错了?就代码本身看,这个ateA.WaitOne(); 要循环50次,但是你却用的是“ateB.Set();”,而不是“ateA.Set();”,因此循环了一次就卡住了,没有Set()信号,第二次WaitOne()就会卡住等待,但是这里始终看不到有Set会给啊。
      

  3.   

    全部代码:
    class Program  
        {  
            static void Main(string[] args)  
            {  
                TheadTest th = new TheadTest();  
                th.Start();  
                Console.ReadKey();  
            }  
        }  
        /// <summary>  
        /// 定义一个线程类  
        /// </summary>  
        class TheadTest  
        {  
            //定义一个Stream对象接收打开文件  
            private FileStream st;  
            //构造方法  
            public TheadTest()    
            {  
            }  
            public void Start()  
            {  
                //定义两个信号锁  
                AutoResetEvent ateA = new AutoResetEvent(false);  
                AutoResetEvent ateB = new AutoResetEvent(false);  
                //把信号锁加入到List中  
                List<AutoResetEvent> lst = new List<AutoResetEvent>();  
                lst.Add(ateA);  
                lst.Add(ateB);  
      
                //定义带参数的输出偶数线程  
                Thread thrEven = new Thread(new ParameterizedThreadStart(OutPutEven));  
                //把两个信号锁传入线程  
                thrEven.Start(lst);  
      
                //定义带参数的输出奇数线程  
                Thread thrOdd = new Thread(new ParameterizedThreadStart(OutPutOdd));  
                thrOdd.Start(lst);             
            }  
      
            private void OutPutEven(object lst)  
            {  
                AutoResetEvent ateA = (lst as List<AutoResetEvent>)[0];  
                AutoResetEvent ateB = (lst as List<AutoResetEvent>)[1];  
      
                for (int i = 0; i < 100; i += 2)  
                {  
                    //设置本线程为无信号  
                    ateA.WaitOne();  
                    //输出  
                    Console.WriteLine(i);  
                    //st = File.Open(@"C:/file.txt", FileMode.Open);      //用来测试同时访问文件系统的  
                    //st.Close();  
                    ateB.Set();  //设置输出奇数线程有信号  
                    //Thread.Sleep(500);  
                }  
            }  
            private void OutPutOdd(object lst)  
            {  
                AutoResetEvent ateA = (lst as List<AutoResetEvent>)[0];  
                AutoResetEvent ateB = (lst as List<AutoResetEvent>)[1];  
                //设置偶数线程先输出  
                ateA.Set();  
                for (int i = 1; i < 100; i += 2)  
                {  
                    //设置本线程为无信号  
                    ateB.WaitOne();  
                    Console.WriteLine(i);  
                    //st = File.Open(@"C:/file.txt", FileMode.Open);     //用来测试同时访问文件系统的  
                    //st.Close();  
                    ateA.Set(); //设置输出偶数线程有信号  
                    //Thread.Sleep(500);  
                }  
            }  
        }    
      

  4.   

    MSDN线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。 如果 AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set 来通知资源可用。调用 Set 向 AutoResetEvent 发信号以释放等待线程。 AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。 如果没有任何线程在等待,则状态将无限期地保持为终止状态。如果当 AutoResetEvent 为终止状态时线程调用 WaitOne,则线程不会被阻止。 AutoResetEvent 将立即释放线程并返回到非终止状态。哪位朋友能不能解释一下上面的话,我看不懂呢,可以用最最最通俗的话来解释
    线程被释放?什么意思?
      

  5.   

    AutoResetEvent就好象地铁闸门,你过去的时候刷一下卡,它让一个人过去,然后就会自动恢复为关闭状态。假设开启操作是用电磁吸引控制的,那么关闭操作就是“无信号”。
      

  6.   

    嗯,这个什么“无信号、有信号”的说法确实比较绕,而且完全可以反过来解释,所以这个解释看起来确实不靠谱。其实Set的意思就直接用英文好了,还是根本避开“有信号、无信号”更加容易让程序员理解。
      

  7.   

    线程阻塞成立的一对条件:
    1.线程中包含waitone();
    2.AutoResetEvent(bool)的bool为false,即事件状态为非终止状态;set()方法是将事件状态设置为终止状态(其实就是破坏第2个条件),允许一个或多个等待线程继续。
      

  8.   

    对这段话,我还是不明白
    MSDN线程通过调用 AutoResetEvent 上的 WaitOne 来等待信号。 如果 AutoResetEvent 为非终止状态,则线程会被阻止,并等待当前控制资源的线程通过调用 Set 来通知资源可用。调用 Set 向 AutoResetEvent 发信号以释放等待线程。 AutoResetEvent 将保持终止状态,直到一个正在等待的线程被释放,然后自动返回非终止状态。 如果没有任何线程在等待,则状态将无限期地保持为终止状态。如果当 AutoResetEvent 为终止状态时线程调用 WaitOne,则线程不会被阻止。 AutoResetEvent 将立即释放线程并返回到非终止状态。
    哪位朋友能不能解释一下上面的话,我看不懂呢,可以用最最最通俗的话来解释
    线程被释放?什么意思?
      

  9.   

    AutoResetEvent  有两种状态  一种终止状态,另一种 非终止状态构造函数有个bool参数,true 是终止, false 是非终止 WaitOne 是用来等待的,如果AutoResetEvent 处于 非终止状态 那么会一直等待,直至调用 Set如果是终止状态 ,那么不会阻塞 会继续调用 Set 就是告知 我的工作完成了,我现在可以走了 ,大家久等了.
      

  10.   


    真的很难懂啊,是不是和Monitor类的Pulse、Wait方法一个意思呢?
    一个用于唤醒其他线程,一个用于阻止本线程
    Monitor.Pulse();
    Monitor.Wait();
      

  11.   

    WaitOne()是用来等待线程的(挂起),Set()是用来设置线程信号状态可调用的的。当调用过Set()了以后,WaitOne()下面的代码会继续执行!
      

  12.   

    是不是和Monitor类的Pulse、Wait方法一个意思呢?
    ------------------------------------------
    不太一样,但是能实现同样的功能,比如多个线程之间切换着执行 可能我之前说到不准确,AutoResetEvent 是用于多线程之间的"调度",通过信号量来实现如果有多个线程,共用一个AutoResetEvent ,那么调用WaitOne 方法的线程将会等待如果是线程切换执行,那么应该是1个线程执行,其余的线程都调用 WaitOne 方法等待当执行的线程调用 SET 方法时,会发出信号量 告知所有等待的线程可以执行但只会有一个线程被执行,其余还是等待.  
      

  13.   


    Console.WriteLine("0");AutoResetEvent autoResetEvent = new AutoResetEvent(false);new Thread(_ => { for (int i = 1; i < 100; i += 2) { Console.WriteLine(i.ToString()); autoResetEvent.Set(); Thread.Sleep(1); } }).Start();
    new Thread(_ => { for (int i = 2; i < 101; i += 2) { autoResetEvent.WaitOne(); Console.WriteLine(i.ToString()); } }).Start();Console.ReadLine();
      

  14.   

    Thread.Sleep(1); 是要让另外的线程有执行的机会,否则基数线程会连续执行.WaitOne 这个方法是始终等待信号量,就是排队
      

  15.   

    楼主不要去想什么是AutoResetEvent的终止状态,什么是非终止状态,这样一点意义都没有,因为AutoResetEvent、waitonet和set()是结合在一起使用的,应该考虑什么情况下线程会阻塞,什么情况下会释放。还有自己也要把线程的概念给搞清楚。
      

  16.   

    有个问题,我这样理解正确不?Set()代码执行之后,WaintOne()后面的代码就要开始执行
    Set的那个线程,发出了通知,WaintOne的那个线程接收到了通知,因为先前它一直阻塞在WaintOne()这句代码这里,一旦接到通知,WaintOne之后的代码,立刻开始执行。并且Set()之后的代码和WaintOne之后的代码是同时进行的
    这样理解正确否?
      

  17.   

    调用set 方法的线程是不在等待队列里的(因为它有机会set)而在set 之前,其他的线程都回在 WaintOne 这句等待,如果接受到set的信号,那么回从等待队列中选一个出来 ,其他线程继续等待.直至下次set.  之前从等待队列出来的线程会持续执行,如果之后运行的代码中没有WaintOne的话如果有的话,也会重新加入到等待的队列中.之前调用set 的方法 是会一直执行的
      

  18.   

    对于ManualResetEvent和AutoResetEvent
    你们通常叫的啥?开关?监视器?信号?