I have question regarding threading in c#.See the code posted below.
public class TestThreading
{
private System.Object lockThis = new System.Object();
public void Function1()
{
lock (lockThis)
{
// Access thread-sensitive resources.
}
}
public void Function2(){
lock (lockThis)
{
// Access thread-sensitive resources.
}
}
}
Now my question is if some thread entered in Function1 (inside lock block) and at the same time another thread enters in Function2 what will happen
The threads will execute independently.
The thread which entered in Function 2 Goes to waits until lock is released by Funtion1 thread.
The thread which entered in Function 2 throws exception.
I am new to c# hence asking simple basic question.
Thanks in advance.
The thread which entered in Function 2 Goes to waits until lock is released by Funtion1 thread.
The purpose of the lock is just that: provide a "safe" region of code that can be accessed only by one thread at a time. The other thread will be put to sleep, and resumed when the first one releases the lock.
Number 2 will happen. The second thread will wait for the lock to be released before executing.
The second thread will wait for the first one to release the lock and only then it will acquire the lock and preform your code
I suggest reading the following articles which describe MultiThreading issues and libraries
Managed Threading Best Practices
Threading in C#
Joseph Albahari
Related
I have a code which synchronize threads via AutoResetEvent
Basically there are two threads which swap control and execute commands , each thread at a time.
Code :
static EventWaitHandle _waitHandle = new AutoResetEvent(false);
static void Waiter()
{
_waitHandle.WaitOne();
Console.WriteLine("A...");
_waitHandle.Set();
_waitHandle.WaitOne();
Console.WriteLine("A2...");
_waitHandle.Set();
}
static void Waiter2()
{
_waitHandle.WaitOne();
Console.WriteLine("B...");
_waitHandle.Set();
_waitHandle.WaitOne();
Console.WriteLine("B2...");
}
void Main()
{
new Thread(Waiter).Start();
new Thread(Waiter2).Start();
_waitHandle.Set(); // Wake up the Waiter.
}
Result : (I always get this result)
A...
B...
A2...
B2...
However - when I move to Tasks :
Task.Run(()=>Waiter());
Task.Run(()=>Waiter2());
I sometimes get :
B...
A...
B2...
Which is clear to me because the task scheduler scheduled the second task to execute first.
Which leads me to ask :
Questions
1) Do threads order guaranteed to be the same as order of invocation in :
new Thread(Waiter).Start();
new Thread(Waiter2).Start();
//In other words , will I always get the first result ?
2) How can I Force the Task.Runs to be invoked the same order as I invoke them?
No, it is not guaranteed, you just got lucky that the output was the same every time.
Add in a 2nd AutoResetEvent that has a WaitOne between the two tasks and a Set in at the start of the Waiter method.
Without a synchronization mechanism, you cannot guarantee the order in which a thread will start and/or execute. Furthermore, a thread's execution may be preempted (think: "paused") at any time.
So to answer your questions:
No
No
Before moving forward, you should ask yourself "Do I really need to use threads to solve this problem?"
My favorite quote from the Microsoft's MSDN:
"When you use multithreading of any sort, you potentially expose yourself to very serious and complex bugs" [Best Practices for Implementing the Event-based Asynchronous Pattern]
If you do need to introduce threads, then I would begin by familiarizing yourself with some of Microsoft's synchronization mechanisms:
Critical Section
Mutex
Events
Auto Reset
Manual Reset
In my application I use a ReaderWriterLockSlim to synchronize reads and writes from/to a list<>.
In the following example reading the list is performed inside all 3 sub-methods, thus these 3 should be packed into a ReadLock. The problem is that SubMethod3 is called via a BackgroundWorker (as it contains lengthy calculations), so the ExitReadLock() in the finally block of MainMethod1 might be called before SubMethod3 has been finished by the BackgroundWorker (separate thread). Thereby the code in SubMethod3 is not really protected by the lock.
What I have considered is to use a lock in each sub-method, so Submethod3 would have its own lock, which would be released when the BackgroundWorker was done. The problem with this approach is that another thread could enter in between the calls of the sub-methods, as each of these would release the lock when done.
My question is: How can ReadLock be used to protect over more threads?
ReaderWriterLockSlim synchronizationLock = new ReaderWriterLockSlim();
public void MainMethod1()
{
synchronizationLock.EnterReadLock();
try
{
SubMethod1(); //Run on UI thread
SubMethod2(); //Run on UI thread
myBackgroundWorker.RunWorkerAsync();
}
finally
{
synchronizationLock.ExitReadLock();
}
}
private void myBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
SubMethod3(); //Run on separate thread
}
In general you are out of luck. Due to thread affinity, you cannot release the lock from another thread. If you try to hold the reader lock (with the idea that this will allow the worker to acquire its own read lock), and wait the worker thread to start, acquire a reader lock and notify you, so you can release the read lock at that time, all you'll get would be a deadlock if there is a waiting writer thread due to reader/waiter fairness of the ReaderWriterLock(Slim) implementation.
I see the following options:
(A) Run the whole MainMethod1 on a separate thread.
(B) Write and use your own reader/writer lock implementation that supports such scenario.
(C) Get rid of BackgroundWorker and switch to async/await implementation using one of the AsyncReaderWriterLock implementations described here ReaderWriterLockSlim and async\await
(D) Since I've noticed the comment Run on UI thread, only and only if the method is used by a thread that supports marshalling calls from another thread (which is true for WF and WPF UI threads), you can use the following technique:
public void MainMethod1()
{
synchronizationLock.EnterReadLock();
bool releaseLock = true;
try
{
SubMethod1();
SubMethod2();
RunWorkerCompletedEventHandler onRunWorkerCompleted = null;
onRunWorkerCompleted = (sender, e) =>
{
((BackgroundWorker)sender).RunWorkerCompleted -= onRunWorkerCompleted;
synchronizationLock.ExitReadLock();
};
myBackgroundWorker.RunWorkerCompleted += onRunWorkerCompleted;
myBackgroundWorker.RunWorkerAsync();
releaseLock = false;
}
finally
{
if (releaseLock)
synchronizationLock.ExitReadLock();
}
}
Please note than while option (D) seems to solve the issue in the context of MainMethod1, it can easily lead to a deadlock if the UI thread tries to acquire read lock from another place and there is a pending writer waiting.
In general working with long time hold locks from the UI thread is a bad idea that is causing more problems rather than solving something. IMO the best are the options (A) and (C), and so far (A) is the simplest if you can afford it (if SubMethod1 and SubMethod2 do not need to be run on the UI thread or can marshall the necessary calls to it).
I am exploring threading concept,
Every time when i tried to execute the below code, I am getting different output.
I am starting ThreadOne first, But why is ThreadTwo getting started.
Why am I getting Different output? Can someone explain in Detail?
Thanks In Advance.
static Object newLockobj = new Object();
static void Main(string[] args)
{
Thread tobj1 = new Thread(ThreadOne);
Thread tobj2 = new Thread(ThreadTwo);
tobj1.Start();
tobj2.Start();
Console.ReadLine();
}
static void ThreadOne()
{
Console.WriteLine("Thread One Entered");
lock (newLockobj)
{
Console.WriteLine("Thread 1 started");
Thread.Sleep(2000);
Console.WriteLine("Thread 1 ended");
}
}
static void ThreadTwo()
{
Console.WriteLine("Thread Two Entered");
lock (newLockobj)
{
Console.WriteLine("Thread 2 started");
Thread.Sleep(1000);
Console.WriteLine("Thread 2 ended");
}
}
This is a basic examle for Concurrency. Once you call the .Start() method on a thread object, it starts getting executed independent of the thread that started it. What your programm is doing:
Create the thread objects
Start tobj1 (the thread is not executed directly, but once the scheduler finds a place to put it)
Start tobj2 (the thread is again not executed directly)
The scheduler is responsible to tell the processor which process and which thread to execute. The order in which the threads are started is of no importance.
As soon as one thread starts, he prints the first line ("Thread X Entered"). The Lock is a synchronization statement. Since both threads sync on the same object instance, they cannot enter the Lock block both (Mutual Exclusion). The Lock statement only ensures that the process can work in the critical section without the other process working it his critical section. As you see in your right output, a thread can be interrupted although he is in his critical section ("Thread 2 started", "Thread One Entered", "..."). "Thread One", however, is not allowed to his critical section since the other thread did not release the lock yet.
This is in the heart of threads programming. While you have control over which thread you want to start first, the CPU is not obliged to follow your order of events. During the execution of one thread the CPU is guaranteed to follow you order of code execution as per your programming. When it comes to scheduling different threads, the CPU will follow its own logic and sometimes that logic can seem like random behavior. It will allocate processing time to different threads as it sees fit.
I suggest you read up more on threads programming as not fully understanding this concept and appreciating it's potential pitfalls will lead to many days of hair pulling and possible deadlocks :)
Just google: c# threading. You will get plenty of good resources!
I hava a class:
public class LockTest
{
public void LockThis()
{
lock (this)
{
Console.WriteLine("lock this test");
System.Threading.Thread.Sleep(5000);
}
}
}
in Main:
static void Main(string[] args)
{
LockTest lockTest = new LockTest();
lock (lockTest)
{
//lockTest.LockThis();
System.Threading.Thread thread = new Thread(lockTest.LockThis);
thread.Start();
}
Console.Read();
}
I thought the invoking lockTest.LockThis() will cause a dead lock but it didn't. I don't konw why.
The explanation here is timing.
The code in Main that starts the thread manages to escape the lock before the thread has fully started and gotten to the point where it too will try to take the lock.
Try moving the Console.Read line into the lock block, and you'll see what I mean.
Also note that even if the thread managed to reach the locking code before the Main method has escaped the lock, it will simply wait for that to happen (wait for the main thread to escape the lock), and then continue onwards.
So there is no deadlock here, at all.
A deadlock is when two threads wait for each other, or something similar. You don't have that in this code.
There can be no deadlock in this code.
When the thread LockThis starts, the lock is owned by the main thread, so it starts and then it goes on wait. The main thread continues and exits the lock (the line before the Console.Read). At this time the LockThis thread can continue. No deadlock.
Main Thread LockThis
lock (not started)
start LockThis
try lock, failure, goes in wait
unlock
Console.Read()
awakened because the lock is free
lock
unlock
Another scenario: the main thread starts the LockThis thread. The main thread then continues and exits the lock before the LockThis thread has even begun working, so before it tries to enter the lock. Even in this scenario there is no deadlock.
Main Thread LockThis
lock (not started)
start LockThis
unlock
lock
Console.Read()
unlock
(note that in both cases, the position of the unlock in LockThis is irrelevant. You can move it up or down)
If you look at the wiki you'll see that to have a deadlock one has to have
At least two resources must be non-shareable.
You here have only one resource (the lock (lockTest)).
You are leaving the lock(lockTest) block before the thread locks lockTest.
I am using the thread.Abort method to kill the thread, but it not working. Is there any other way of terminating the thread?
private void button1_Click(object sender, EventArgs e)
{
if (Receiver.IsAlive == true)
{
MessageBox.Show("Alive");
Receiver.Abort();
}
else
{
MessageBox.Show("Dead");
Receiver.Start();
}
}
I am using this but every time I get the Alive status, Receiver is my global thread.
The reason it's hard to just kill a thread is because the language designers want to avoid the following problem: your thread takes a lock, and then you kill it before it can release it. Now anyone who needs that lock will get stuck.
What you have to do is use some global variable to tell the thread to stop. You have to manually, in your thread code, check that global variable and return if you see it indicates you should stop.
You can kill instantly doing it in that way:
private Thread _myThread = new Thread(SomeThreadMethod);
private void SomeThreadMethod()
{
// do whatever you want
}
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
private void KillTheThread()
{
_myThread.Abort();
}
I always use it and works for me:)
You should first have some agreed method of ending the thread. For example a running_ valiable that the thread can check and comply with.
Your main thread code should be wrapped in an exception block that catches both ThreadInterruptException and ThreadAbortException that will cleanly tidy up the thread on exit.
In the case of ThreadInterruptException you can check the running_ variable to see if you should continue. In the case of the ThreadAbortException you should tidy up immediately and exit the thread procedure.
The code that tries to stop the thread should do the following:
running_ = false;
threadInstance_.Interrupt();
if(!threadInstance_.Join(2000)) { // or an agreed resonable time
threadInstance_.Abort();
}
thread will be killed when it finish it's work, so if you are using loops or something else you should pass variable to the thread to stop the loop after that the thread will be finished.
C# Thread.Abort is NOT guaranteed to abort the thread instantaneously. It will probably work when a thread calls Abort on itself but not when a thread calls on another.
Please refer to the documentation: http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx
I have faced this problem writing tools that interact with hardware - you want immediate stop but it is not guaranteed. I typically use some flags or other such logic to prevent execution of parts of code running on a thread (and which I do not want to be executed on abort - tricky).