AutoResetEvent Reset immediately after Set

前端 未结 4 1117
花落未央
花落未央 2021-02-14 14:33

Consider the following pattern:

private AutoResetEvent signal = new AutoResetEvent(false);

private void Work()
{
    while (true)
    {
        Thread.Sleep(5000         


        
4条回答
  •  梦如初夏
    2021-02-14 15:15

    There is no guarantee. This:

    AutoResetEvent flag = new AutoResetEvent(false);
    
    new Thread(() =>
    {
        Thread.CurrentThread.Priority = ThreadPriority.Lowest;
        Console.WriteLine("Work Item Started");
        flag.WaitOne();
        Console.WriteLine("Work Item Executed");
    }).Start();
    
    // For fast systems, you can help by occupying processors.
    for (int ix = 0; ix < 2; ++ix)
    {
        new Thread(() => { while (true) ; }).Start();
    }
    
    Thread.Sleep(1000);
    Console.WriteLine("Sleeped");
    
    flag.Set();
    // Decomment here to make it work
    //Thread.Sleep(1000);
    
    flag.Reset();
    Console.WriteLine("Finished");
    Console.ReadLine();
    

    won't print "Work Item Executed" on my system. If I add a Thread.Sleep between the Set and the Reset it prints it. Note that this is very processor dependent, so you could have to create tons of threads to "fill" the CPUs. On my PC it's reproducible 50% of the times :-)

    For the Exited:

    readonly object mylock = new object();
    

    then somewhere:

    lock (mylock)
    {
        // Your code goes here
    }
    

    and the WaitForExit:

    void WaitForExit()
    {
        lock (mylock) ;
        // exited
    }
    
    void bool IsExited()
    {
        bool lockTacken = false;
    
        try
        {
            Monitor.TryEnter(mylock, ref lockTacken);
        }
        finally
        {
            if (lockTacken)
            {
                Monitor.Exit(mylock);
            }
        }
    
        return lockTacken;
    }
    

    Note that the lock construct isn't compatible with async/await (as aren't nearly all the locking primitives of .NET)

提交回复
热议问题