C# 需要帮助了解AutoResetEvent行为吗

C# 需要帮助了解AutoResetEvent行为吗,c#,.net,multithreading,.net-core,C#,.net,Multithreading,.net Core,我正在试验.NET的信令结构,并尝试在两个线程之间进行简单的协调,但是出现了一些问题,结果到处都是,程序有时会锁定。我想这是某种比赛状态,但我想有人来解释一下发生了什么 private static readonly AutoResetEvent manual = new AutoResetEvent(false); private static int num; public static async Task Main() { await T

我正在试验.NET的信令结构,并尝试在两个线程之间进行简单的协调,但是出现了一些问题,结果到处都是,程序有时会锁定。我想这是某种比赛状态,但我想有人来解释一下发生了什么

    private static readonly AutoResetEvent manual = new AutoResetEvent(false);
    private static int num;

    public static async Task Main()
    {
        await Task.WhenAll(Task.Run(Method1), Task.Run(Method2));
    }

    private static void Method1()
    {
        num = 100;
        manual.Set();
        manual.WaitOne();
        num -= 1000;
        manual.Set();
    }

    private static void Method2()
    {
        manual.WaitOne();
        var into = num;
        num += into / 2;
        manual.Set();
        manual.WaitOne();
        Console.WriteLine($"final value of num {num}");
    }

是的,这是一个比赛条件

Method 1 Begins
Method 2 cant start before Method 1 because it calls WaitOne in the beginning and the AutoResetEvent is not in the signaled state
Method 1 assigns num = 100
Method 1 sets AutoResetEvent. This notifies a waiting thread that an event has occurred.
其余工作将分为多个场景

情景1:

Method 1 calls WaitOne, consumes AutoResetEvent signaled state and goes to the next line, AutoResetEvent resets.
Method 1 decreases num by 1000 (num = -900 now)
Method 1 signals AutoResetEvent
Method 2 can start cause AutoResetEvent is signlaed. AutoResetEvent resets after Method 2 getting notified.
Method 2 assigns into = num (into = -900)
Method 2 increases num by (into / 2) which makes the final result of num = -1350 (num = -900 - 450)
Method 2 signals AutoResetEvent
Method 2 consumes AutoResetEvent signaled state
Method 2 prints final value
结果是-1350,程序终止,因为这两个任务在此场景中都已完成

情景2:

Instead of method 1, Method 2 calls WaitOne and continues. AutoResetEvent resets.
Method 1 cant go to the next line because it is blocked by WaitOne
Method 2 assigns num to into (into = 100 now)
Method 2 increases num by into/2 (num = 100 + 50 = 150)
Method 2 sets AutoResetEvent.
这里,场景2将分为多个场景。场景2-1和场景2-2

情景2-1:

Method 1 gets notified and decrease num by 1000 (num = 150 - 1000 = -850)
Method 1 sets AutoResetEvent.
Method 2 gets notified and prints the result.
结果是-850,程序终止,因为这两个任务都在此场景中完成

情景2-2:

Method 2 gets notified and prints the result.
Method 1 will be blocked until someone somewhere set the AutoResetEvent.

结果是150,程序不会终止,因为第一个任务尚未完成。

是的,这是一个竞赛条件

Method 1 Begins
Method 2 cant start before Method 1 because it calls WaitOne in the beginning and the AutoResetEvent is not in the signaled state
Method 1 assigns num = 100
Method 1 sets AutoResetEvent. This notifies a waiting thread that an event has occurred.
其余工作将分为多个场景

情景1:

Method 1 calls WaitOne, consumes AutoResetEvent signaled state and goes to the next line, AutoResetEvent resets.
Method 1 decreases num by 1000 (num = -900 now)
Method 1 signals AutoResetEvent
Method 2 can start cause AutoResetEvent is signlaed. AutoResetEvent resets after Method 2 getting notified.
Method 2 assigns into = num (into = -900)
Method 2 increases num by (into / 2) which makes the final result of num = -1350 (num = -900 - 450)
Method 2 signals AutoResetEvent
Method 2 consumes AutoResetEvent signaled state
Method 2 prints final value
结果是-1350,程序终止,因为这两个任务在此场景中都已完成

情景2:

Instead of method 1, Method 2 calls WaitOne and continues. AutoResetEvent resets.
Method 1 cant go to the next line because it is blocked by WaitOne
Method 2 assigns num to into (into = 100 now)
Method 2 increases num by into/2 (num = 100 + 50 = 150)
Method 2 sets AutoResetEvent.
这里,场景2将分为多个场景。场景2-1和场景2-2

情景2-1:

Method 1 gets notified and decrease num by 1000 (num = 150 - 1000 = -850)
Method 1 sets AutoResetEvent.
Method 2 gets notified and prints the result.
结果是-850,程序终止,因为这两个任务都在此场景中完成

情景2-2:

Method 2 gets notified and prints the result.
Method 1 will be blocked until someone somewhere set the AutoResetEvent.

结果是150,程序不会终止,因为第一个任务尚未完成。

是的,这是一场比赛。这种锁定需要Barrier.SignalAndWait()。是的,这是一场竞赛。这种锁定需要Barrier.SignalAndWait()。我明白了,谢谢。我有点假设另一个线程已经在排队等待了,一个方法不能同时设置和使用锁,但这对您来说是多线程的:)我明白了,谢谢。我有点假设另一个线程已经在排队等待了,一个方法不能同时设置和使用锁,但这对您来说是多线程的:)