I have 2 methods TIC and TAC which just output "TIC" or "TAC". And my goal is after creating multiple threads of TIC and TAC. Final result should be: TIC TAC TIC TAC TIC TAC
Here i create threads.
Class1 a = new ();
Thread thread1 = new Thread(() => a.TIC());
Thread thread2 = new Thread(() => a.TIC());
Thread thread3 = new Thread(() => a.TIC());
Thread thread4 = new Thread(() => a.TAC());
Thread thread5 = new Thread(() => a.TAC());
Thread thread6 = new Thread(() => a.TAC());
thread3.Start();
thread5.Start();
thread2.Start();
thread6.Start();
thread4.Start();
thread1.Start();
thread1.Join();
thread2.Join();
thread3.Join();
thread4.Join();
thread5.Join();
thread6.Join();
And here TIC and TAC methods
public class Class1
{
public Mutex mutexTIC = new Mutex(true);
public Mutex mutexTAC = new Mutex(false);
public void TIC()
{
mutexTIC.WaitOne();
Console.WriteLine("TIC");
mutexTAC.ReleaseMutex();
}
public void TAC()
{
mutexTAC.WaitOne();
Console.WriteLine("TAC");
mutexTIC.ReleaseMutex();
}
}
also i tried to add lock, add Mutexs as parameters, tried to use event. But every time i get this System.ApplicationException: 'Object synchronization method was called from an unsynchronized block of code.'. And i have 0 idea how fix it. I'm sorry for any unclearence. Hope i explained enough.
You are getting this exception because you are using Mutex
incorrectly: you are taking mutexTIC
on the main thread, where Class1
is created, but then attempt to release it on a different thread. This restriction exists because Mutex
wraps an OS kernel mutex object which (at least on Windows) enforces these threading rules. ManualResetEvent
and relatives also wrap kernel synchronization objects and have similar restrictions. However, in a managed program, one almost never needs to use these legacy objects (the exception is when you need them to synchronize with other processes or with unmanaged code). Instead of Mutex
, use a managed synchronization object with less restrictive rules, such as SemaphoreSlim
:
// in Class1:
public SemaphoreSlim mutexTIC = new (1, 1);
public SemaphoreSlim mutexTAC = new (0, 1);
public void TIC()
{
mutexTIC.Wait();
Console.WriteLine("TIC");
mutexTAC.Release();
}
public void TAC()
{
mutexTAC.Wait();
Console.WriteLine("TAC");
mutexTIC.Release();
}
Note that this code is fine as a toy example, but if TIC()
and TAC()
did something non-trivial that could throw an exception, you would need to be very careful with exception and error handling so as not to leak semaphore counts and create a deadlock.