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);
}