Threads are blocked due to unable to close database connection - c#

In the stacktrace, MessageProcessor.Dispose(), OnThreadShutdownRequested and RenewTaskLeaseCallback all require a lock to prevent race conditions in these objects.
The stacktrace for thread (ID14968) holds all the locks, which causes the other threads to block and wait for it to release the locks.
The problem is that, when CloseConnection() is called on thread-14968, the connection is never closed, and SyncAsyncLock.Wait() was called internally inside CloseConnection(). Call is blocked and would not continue, and a deadlock situation occurs.
What would possibly cause the thread to block when CloseConnection() was called?
Larger image here.

After working on this issue for two days, I finally figured out the problem.
There was a situation that could result a deadlock in the application.
The TaskLeaseRenewer object implements IDisposable and can be accessed by multiple threads. A lock is used inside the class to make sure no two threads will try to dispose the object at the same time. TaskLeaseRenewer has a timer, and callback function Callback that will be called periodically by the timer, on a separate thread. The Callback thread will try to call Thread.Abort() on the thread that created the TaskLeaseRenewer and eventually call Dispose() on TaskLeaseRenwer
The problem happens when I try to abort the thread that does does the following:
using(TaskLeaseRenewer renewer = new TaskLeaseRewnewer())
{
DoStuff();
}
I found out that when you call Thread.Abort() on a thread with using statements, it will not terminate the thread until it call the Dispose() function on the used object.
The example below will trigger ConnectionWrapper.Dispose() before the thread is aborted.
static void DisposeOnAbort()
{
Thread t = new Thread(() =>
{
Console.WriteLine("Using connection wrapper");
using (ConnectionWrapper wrapper = new ConnectionWrapper())
{
while (true)
{
Thread.Sleep(1000);
}
}
});
t.Start();
Thread.Sleep(1000);
Console.WriteLine("Aborting thread..");
t.Abort();
}
Given these, I found the problem is when Callback() calls Thread.Abort(), TaskLeaseRenewer.Dispose() will be called on the thread it was created because the thread is getting ready to be killed. However Callback() function is on a different thread and also holding the lock the Dispose() function is trying to acquire. Dispose() will not be able to acquire the lock, and the thread will never terminate.
After solving this problem, the connection.Close() deadlock seems to be gone. I am still interested in what could be blocking the connection from closing.
After playing around with this problem more, i find when a thread is aborted, the disposable object's Dispose() object is always called. whether using statement is used or not. Callstack as follows:
Threads.exe!Threads.ConnectionWrapper.Dispose() Line 150 C#
Threads.exe!Threads.Program.DisposeOnAbort.AnonymousMethod__0() Line 58 + 0x2c bytes C#

Related

Will thread be disposed if an object sets to null

I have a class ClassA
public class ClassA
{
public ClassA()
{
Thread t = new Thread(EndlessLoop);
t.IsBackground = True;
t.Start();
}
private void EndlessLoop()
{
while (True)
{
// do something
}
}
}
and I'm not sure if the thread will be disposed if I set ClassA object to null
ClassA a = new ClassA();
# will the thread exit ?
a = null;
Or maybe I should implement IDisposable, and call it manually?
Once started, the thread will terminate after the routine comes to an end (or Thread.Abort is invoked or the program exits). The Thread class doesn't implement IDisposable so there's no Dispose method to call. To terminate a long-running thread, you could set a flag that the thread checks periodically.
The Thread object is eligible to be garbage collected once it goes out of scope and is no longer referenced. However, the spawned thread will continue running.
Nothing going to happen to the OS thread if you remove last refence to the Thread object corresponding to it - C# Thread object lifetime. The thread will continue to run the code until the method finishes (unlikely in while(true) case shown), thread is terminated with Abort (don't do that - What's wrong with using Thread.Abort()) or process ends.
The only good option is to somehow notify thread's code that it should finish (i.e. using events or even global variable protected by lock). Also consider if using Task and async with corresponding cancellation mechanism would simplify code (it would not solve infinite loop issue but give good framework to write cancellable operations).
Note that you can't "dispose" thread because it does not implement Dispose (Do we need to dispose or terminate a thread in C# after usage?),

stopping my thread

I have a thread that I am trying to discontinue. What I have done is the following.
randomImages = new Thread(new ThreadStart(this.chooseRandomImage));
randomImages.Start();
This is the method called by the thread
bool threadAlive = true;
public void chooseRandomImage()
{
while(threadAlive)
{
try
{
//do stuff
}
catch (Exception exe)
{
MessageBox.Show(exe.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
Now, upon clicking a stop thread button I simply set threadAlive to false.
Problem is the thread doesnt stop immediately, as if it has gathered a form of momentum.
How can a stop a thread instantly, and possibly restart it again?
private void butStopThread_Click(object sender, EventArgs e)
{
threadAlive = false;
if(threadAlive == false)
{
//do stuff
}
}
I am sorry, that IS the best way to do it. Using .NET 4.0 upward you should use tasks, not threads, and then there is this thing called CancellationToken that pretty much does the same as your variable.
Then, after cancelling, you wait until the processing is finishing. If that needs to happen fast, then - well - make the check for the cancellation more granular, i.e. check more often.
Aborting threads has possibly significant side effects as explained at http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation - this is why the method generally should not be used.
And no, stopped threads etc. can not be restarted magically - this you have to put into your logic (restart points, save points ,long running transaction in steps, remembering where it finished).
As a sidenote - if you insist on not using tasks and have access to the latest versin of .NET, Volatile is not needed if you use the Interlocked access class methods, which ago down to some assembler instructions that are thread safe per definition.
It is possible to terminate a thread from another thread with a call
to Abort, but this forcefully terminates the affected thread without
concern for whether it has completed its task and provides no
opportunity for the cleanup of resources. The technique shown in this
example is preferred.
You need to use Abort method BUT IS NOT RECOMMENDED
From the information provided by you, it seems the threadAlive variable is being accessed by both the worker thread and the UI thread. Try declaring threadAlive using volatile keyword which is ensure cross-thread access happens without synchronization issues.
volatile bool threadAlive;
To restart the thread, you first need to ensure that it performs all necessary cleanup. Use the Join method call on your thread object in the main/UI thread to make sure your thread terminates safely. To restart, simply invoke the Start method on the thread.
randomImages.Join();

Benefits of Thread.ResetAbort

When a thread is canceled via Thread.Abort(), a ThreadAbortException is thrown inside the Thread on which Thread.Abort() was called on. This leads the thread to immediately stop its work and the exception bubbles up the call stack until it leaves the thread's main method. This causes the thread to be aborted.
What are the benefits of an ExceptionHandler for the ThreadAbortException in the threads main method where Thread.ResetAbort() is called, when the thread terminates itself anyway after the catch block due to stepping out its main method?
private void ThreadMainMethod( )
{
try
{
while(runningAllowed = true)
{
//Do some work here
}
}
catch ( ThreadAbortException )
{
Thread.ResetAbort( );
}
}
One scenario I can think of is that you want to take down the thread in a controlled manner. Let's say you have a worker thread that is polling some resource. If the application's main thread invokes Abort on the worker thread, a ThreadAbortException is thrown. You can then catch that exception in start method for the worker thread, call ResetAbort and then finish the method by releasing resource, closing open files/connections and so on:
public void ThreadStarter()
{
try
{
RunWorkerLoop();
}
catch (ThreadAbortException)
{
Thread.ResetAbort();
}
// clean up and end gracefully
}
Probably the only reason you'd do that would be if you were in a great position to decide whether or not you should actually abort.
So perhaps the thread would catch it, check the status of something, and then go back about its work again. Though this does imply that you're basically using the '.abort()' to control the flow of this thread. And that's quite a bad idea. You should communicate with it in another way.
In general, I would think there are not many cases where this is a good idea, and it wouldn't be the advice for any particular pattern or implementation I can think of.
In you particular case it doesn't really make a difference, because the thread will be terminated once the method is done running.
However, in other case you may have a method that runs in an endless loop. In this case, you can shutdown the thread using the ThreadAbortException (I am not saying that you should, but you could). If the thread for some reason determines to continue despite the exception it needs to call ResetAbort to prevent the runtime to automatically rethrow the ThreadAbortException.
I found that calling ResetAbort() to be of great help in this elegant implementation of the WaitFor with time-out pattern .

How to kill a thread instantly in C#?

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).

C# thread interruption stopped working

I dont know why but i can no longer interrupt my own thread.
thread = new Thread(new ParameterizedThreadStart(this.doWork));
thread.Start(param);
...
thread.Interrupt();
//in doWork()
try {
...
}
catch (System.Threading.ThreadInterruptedException)
{
//it never hits here. it use to
}
I search and i dont have any catch in my code and this is the only catch (System.Threading.ThreadInterruptedException). So what is going on? Using the debugger i can see my code run through the thread.Interrupt();. If i do thread.abort() i will catch a System.Threading.ThreadAbortException exception. Why is it catching that and not ThreadInterruptedException?
From BOL:
Interrupts a thread that is in the
WaitSleepJoin thread state.
If this thread is not currently
blocked in a wait, sleep, or join
state, it will be interrupted when it
next begins to block.
ThreadInterruptedException is thrown
in the interrupted thread, but not
until the thread blocks. If the thread
never blocks, the exception is never
thrown, and thus the thread might
complete without ever being
interrupted
BTW, you might be better off using the BackgroundWorker Class which supports cancelling.
From acidzombie24's comment to another answer:
So .abort is a better option? What i want to do is kill the thread but have it exist and call a few functions instead of outright death
Something like an event would be better.
Assuming you want to be able to signal each thread separately, before each worker thread is started create an AutoResetEvent and pass it to the thread.
When you want to interrupt the thread call Set on the event. In the worker thread check the state of the event regularly:
if (theEvent.WaitOne(TimeSpan.Zero)) {
// Handle the interruption.
}
(Regularly: needs to be defined by the requirements: overhead of checking vs. latency of interruption.)
To have a master interrupt, to signal all workers, use a ManualResetEvent which will stay signalled, and keep interrupting threads when they check, until explicitly Reset.

Categories

Resources