锁定基本类型

Ola*_*cea 8 c# multithreading

我想检查一些锁定行为,我无法理解:

static void Main(string[] args)
{
    for (int i = 0; i < 10; i++)
    {
        Task.Factory.StartNew(() =>
        {
            MultithreadedMethod();
        });
    }

    Thread.Sleep(2000);
    Console.WriteLine(count);
}

static int count = 0;
private static readonly int sync = 5;

public static void MultithreadedMethod()
{
    if (Monitor.TryEnter(sync))
    {
        count++;
        Monitor.Exit(sync);
    }
}
Run Code Online (Sandbox Code Playgroud)

我认为这应该不起作用,因为我正在对整数值进行同步.First Boxing,然后是Unboxing,我应该得到一个System.Threading.SynchronizationLockException,因为缺少同步块根(我知道这是特定于引用类型).我不会欺骗自己,即使这适用于几次迭代,它也不是真的同步..所以,考虑到增量操作的非原子属性..我不会得到确定性的结果..我知道这个.

事实上,当我摆脱Thead.Sleep并对任务进行等待时......异常就会到位.

Task.Factory.StartNew(() =>
 {
       MultithreadedMethod();
 }).Wait();
Run Code Online (Sandbox Code Playgroud)

我认为应该抛出异常: Monitor.Exit(sync)

有什么能吸引它的?

更新1:pic添加.

在此输入图像描述

Yuv*_*kov 6

有什么能吸引它的?

Task对象内部抛出的异常在其中隐式捕获Task.除非您访问Task.ExceptionTask.Wait/Task.Result属性或await返回的任务,否则将吞下异常并且您将无法看到它.这就是使用Wait传播异常的原因,您可以在控制台中看到它.如果您Task.WaitAll等待所有任务完成,也会发生同样的情况.

如果您不使用其中任何一项,您仍然可以通过注册到TaskScheduler.UnobservedTaskException以下内容来查看例外:

static void Main(string[] args)
{
    TaskScheduler.UnobservedTaskException += (s,e) => Console.WriteLine(e.Exception);

    for (int i = 0; i < 10; i++)
    {
        Task.Factory.StartNew(() =>
        {
            MultithreadedMethod();
        });
    }

    Thread.Sleep(2000);
    Console.WriteLine(count);
}
Run Code Online (Sandbox Code Playgroud)

产量:

未观察到的任务异常

请注意,此代码仍具有竞争条件,因为我们实际上并未等待任何结果,这可能不会在2秒的睡眠后发生.