我想检查一些锁定行为,我无法理解:
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添加.
有什么能吸引它的?
在Task对象内部抛出的异常在其中隐式捕获Task.除非您访问Task.Exception或Task.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秒的睡眠后发生.
| 归档时间: |
|
| 查看次数: |
232 次 |
| 最近记录: |