Primitive type lock

I want to check some locking actions, and I cannot figure it out:

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

I thought this should not work due to the fact that I am performing synchronization on an integer value. The first box, then Unboxing, and I should get a System.Threading.SynchronizationLockException due to the missing root of the synchronization block (I know this refers to link types). I am not going to fool myself, even if it works for several iterations, it does not sync. Therefore, given the non-atomic property of the increment operation, I will not get deterministic results. I know it.

In fact, when I get rid of this Thead.Sleep and put Wait in Task. An exception occurs.

 Task.Factory.StartNew(() => { MultithreadedMethod(); }).Wait(); 

I think there should be an exception: Monitor.Exit(sync)

but what catches him?

Update 1: pic added.

enter image description here

+6
source share
2 answers

but what catches him?

The exception created inside the Task object is implicitly caught inside the Task . If you do not get access to the properties of Task.Exception or Task.Wait/Task.Result or await in the returned task, the exception will be swallowed and you will not be able to see it. This is why using Wait exception, and you can see it in the console. The same thing happens if you use Task.WaitAll to wait for all tasks to complete.

If you are not using any of them, you can still see this exception by registering for 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); } 

Productivity:

Stealth task exception

Please note that this code still has race conditions due to the fact that we do not expect results that can occur after sleep within 2 seconds.

+4
source

When I run my code, I see in the "Exit" window:

An exception was thrown: 'System.Threading.SynchronizationLockException' in ConsoleApplication5.exe

I assume that you are not catching exceptions emanating from tasks (and your IDE is not set to break when they are unhandled). Instead of a sleeping thread, try the following:

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

WaitAll display exceptions.

+2
source

All Articles