C# 锁定基元类型

C# 锁定基元类型,c#,multithreading,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 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);
    }
}
我认为这里应该抛出一个异常:
Monitor.Exit(sync)

但是什么抓住了它

更新1:添加了图片。


运行代码时,我在输出窗口中看到:

引发异常:ConsoleApplication5.exe中的“System.Threading.SynchronizationLockException”

我猜您没有捕获来自任务的异常(并且您的IDE在未处理它们时没有设置为中断)。尝试以下操作,而不是休眠线程:

List<Task> tasks = new List<Task>();
for (int i = 0; i < 21000; i++)
{
    tasks.Add(Task.Factory.StartNew(() =>
    {
        MultithreadedMethod();
    }));
}

Task.WaitAll(tasks.ToArray());
List tasks=newlist();
对于(int i=0;i<21000;i++)
{
tasks.Add(Task.Factory.StartNew(()=>
{
多线程方法();
}));
}
Task.WaitAll(tasks.ToArray());
WaitAll
将显示异常

但是什么抓住了它

任务
对象中引发的异常将在该
任务
中隐式捕获。除非对返回的任务访问
Task.Exception
Task.Wait/Task.Result
属性,或
Wait
,否则异常将被吞噬,您将无法看到它。这就是为什么使用
Wait
传播异常,您可以在控制台中看到它。如果使用
Task.WaitAll
等待所有任务完成,也会发生同样的情况

如果您不使用这些选项中的任何一个,您仍然可以通过注册到以下位置来查看异常:

static void Main(字符串[]args)
{
TaskScheduler.unobservedtaskeexception+=(s,e)=>Console.WriteLine(e.Exception);
对于(int i=0;i<10;i++)
{
Task.Factory.StartNew(()=>
{
多线程方法();
});
}
《睡眠》(2000年);
控制台写入线(计数);
}
收益率:


注意,由于我们实际上没有等待任何结果的出现,这段代码仍然存在争用条件,这可能不会在睡眠2秒后发生。

当我运行上述代码时,它确实会从
退出
引发异常。确定要从任务中捕获异常吗?@PatrickHofman这是我所有的。刚刚拍了这张照片。
List<Task> tasks = new List<Task>();
for (int i = 0; i < 21000; i++)
{
    tasks.Add(Task.Factory.StartNew(() =>
    {
        MultithreadedMethod();
    }));
}

Task.WaitAll(tasks.ToArray());
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);
}