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?),
Related
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#
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();
I have a class that uses the Thread class:
class A
{
public Thread thread
{ get; set; }
}
Should I implement IDisposable and set Thread property to null?
class A : IDisposable
{
public Thread Thread
{ get; set; }
protected bool Disposed
{ get; set; }
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.Disposed)
{
if (disposing)
{
if (Thread != null)
Thread = null;
}
Disposed = true;
}
}
}
Or not?
Why?
You implement IDisposable only when your class is handling an unmanaged object, resources or other IDisposable objects. A Thread is not an unmanaged object and will get garbage collected when nothing is referencing it or when the process handling it is terminated. Since Thread is not implementing IDisposable, your class referencing it does not need to implement it either.
Optionally, for IDisposable within the scope of a method, they can be wrapped in a using statement and the Dispose() method is automatically called when the scope is exited.
It depends what your thread is doing. If your thread is performing a long running task that may run indefinitely, then I would consider that thread as a resource (which will not be garbage collected). For example consider if the thread is designed to poll some state indefinitely, or consume items from a queue (like a thread-pool thread consumes tasks or a TCP server consumes new connections) etc. In this case, I would say the natural effect of disposing your class would be to free up this thread resource. Setting it to null is not really useful in this case. Rather Dispose should probably involve flagging a synchronization event (or maybe a CancellationToken) to notify the thread that it should finish up its infinite task, and then the disposing thread should wait some time for the thread to finish (join). As always with joins, be careful of a deadlock scenario and consider some alternative action if the thread refuses to terminate. For obvious reasons I would not do this join in the finalizer.
As an example of what I'm meaning, consider the scenario where your class A is actually class MyTcpListener, designed to listen and wait for new TCP connections on a given port indefinitely. Then consider what you expect following (somewhat unlikely) code to do:
using (MyTcpListener listener = new MyTcpListener(port:1234))
{
// Do something here
}
// Create another one. This would fail if the previous Dispose
// did not unbind from the port.
using (MyTcpListener listener = new MyTcpListener(port:1234))
{
// Do something else here
}
Assuming I know the constructor of MyTcpListener creates a listener thread, I would expect that after the Dispose call has returned that the MyTcpListener would no longer be bound to the TCP port - i.e. that the TCP listener thread would have fully terminated. It goes without saying that if you didn't provide some mechanism to stop the listener that there would be a resource leak. The stopping mechanism could be a call to some method "Stop", but I personally think the "Dispose" pattern fits this scenario more cleanly since forgetting to stop something does not generally imply a resource leak.
Your code may call for different assumptions, so I would suggest judging it on the scenario. If your thread is short-running, e.g. it has some known finite task to complete and then it will terminate on its own, then I would say that disposing is less critical or perhaps useless.
I'm trying to make cross-threaded calls in C#.
Whenever I invoke the methods of an object created in the context of thread A from a static method called from thread B, the method always runs in thread B. I don't want that, I want it run on the same thread as the thread A object whose methods I am calling.
Invoke works fine for UI calls and I've read dozens of articles and SO answers relating to different ways of making cross-threaded Forms/WPF calls. However whatever I try (event handling, delegates, etc) Thread A's object's method will always run in Thread B if it is invoked by Thread B.
What part of the library should I be looking in to solve this? If it's relevant, Thread B currently 'spins', reads from a network port and occasionally invokes Thread A's object's method through a delegate that was created in Thread A and passed in using a ParameterizedThreadStart.
I'm not looking to change paradigm, just send a message (a request to invoke a method) from one thread (Thread B) to another (Thread A).
EDIT:
My question was 'what part of the library should I be looking in to solve this?' The answer appears to be none. If I want to clearly delineate consumption and polling I'll have to write my own code to handle that.
Whenever I invoke the methods of an object running on thread A
Objects don't run on threads.
In order for this to work, you will have to create some kind of queue you can shove a delegate into that will be routinely checked thread A's main loop. Something like this, assuming that Something.MainThreadLoop is the entry point for thread A:
public class Something
{
private Queue<Action> actionQueue = new Queue<Action>();
private volatile bool threadRunning = true;
public void RunOnThread(Action action)
{
if (action == null)
throw new ArgumentNullException("action");
lock (actionQueue)
actionQueue.Enqueue(action);
}
public void Stop()
{
threadRunning = false;
}
private void RunPendingActions()
{
while (actionQueue.Count > 0) {
Action action;
lock (actionQueue)
action = actionQueue.Dequeue();
action();
}
}
public void MainThreadLoop()
{
while (threadRunning) {
// Do the stuff you were already doing on this thread.
// Then, periodically...
RunPendingActions();
}
}
}
Then, given a reference to a Something object, you could do this:
something.RunOnThread(() => Console.WriteLine("I was printed from thread A!"));
Code runs on threads. Objects aren't (generally - see thread local) bound to a particular thread. By doing WinFormControl.Invoke or WPFControl.Invoke, you are posting a message to the Message Pump or Dispatcher respectively, to run some code at a later date.
The message pump is something like this:
Message message;
while(GetMessage(&message))
{
ProcessMessage(message);
}
Microsoft has specifically built their UI controls and projects to allow the posting of messages across threads. Calling a method from thread A will always execute that method on thread A, even if it ends up doing some kind of asynchronous work and returning early.
Edit:
What it is I think you need is the Producer Consumer pattern.
http://msdn.microsoft.com/en-us/library/yy12yx1f(VS.80).aspx
Forget about consuming the messages from your main thread, which is what it sounds like you want to do. Consume from thread C.
Thread A is doing 'much more important things'. Thread B is spinning, listening for messages. Thread C is consuming those messages.
No need for marshalling across threads.
EDIT: I think you probably want to use the System.Threading.AutoResetEvent class. The MSDN documentation has a decent example of one thread waiting on the other that I think is similar to what you are trying to do: http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx
In particular, pay attention to the calls to trigger.WaitOne() and trigger.Set()
EDIT2: Added option #3 after reading new comment from OP.
"Whenever I invoke the methods of an object running on thread A ..." - An object doesn't "run" on a thread and isn't really owned by any thread, regardless of what thread created the object.
Given that your question is regarding "non-UI cross-thread invocation", I assume you are already familiar with "UI cross-thread invocation". I can see how WinForms would give you an impression that a thread owns an object and that you need to "send a message" to a thread in order to make it do something.
WinForm control objects are kind of a special case in that they simply don't function properly if you interact with them with a thread that isn't the one that created them, but that's not caused by the way that threads and objects interact.
Anyway, on to addressing your question.
First, a question to clarify the problem: You've mentioned what Thread B is doing, but what is Thread A doing prior to being "invoked" by Thread B?
Here are a couple of ideas that I think are along the lines of what you want to do:
Don't create Thread A until you need to. Instead of having Thread B "send a message to Thread A", rather have Thread B create Thread A (or call it Thread C if you prefer) and make it start executing at that time.
If you need Thread A to already exist and you only want Thread A to handle Thread B's events one at a time, you could have Thread A wait until it receives a notification from Thread B. Take a look at the System.Threading.WaitHandle class (derived classes of interest are ManualResetEvent and AutoResetEvent).
Thread A will at some point call WaitHandle.WaitOne(), which will cause it to pause and wait until Thread B calls WaitHandle.Set() on the same WaitHandle object.
If Thread A is busy doing other things, then you might want to set up some kind of flag variable. Similar to the WaitHandle concept in #2, but instead of causing Thread A to pause, you just want Thread B to set a flag (perhaps just a boolean variable) that will signal to Thread A that it needs to do something. While Thread A is busy doing other things, it can periodically check that flag to decide whether or not there is work that needs to be done.
Does the method that Thread A will execute on your object require any input from Thread B? Then before Thread B calls WaitHandle.Set(), have it stick some data into a queue or something. Then, when Thread A is "activated", it can retrieve that data from the queue and proceed to execute the object's method using that data. Use a lock mechanism (i.e. the C# lock statement) to synchronize access to the queue.
What you're going to have to do is roll a sort of Queue and have Thread A watch that queue for work. When Thread A sees new work enter the queue, it can dequeue it and do the work, then return to waiting for more.
Here's some pseudo-code:
public class ThreadAQueue
{
private Queue<delegate> _queue;
private bool _quitWorking;
public void EnqueueSomeWork(delegate work)
{
lock(_queue)
{
_queue.Enqueue(work);
}
}
private void DoTheWork()
{
while(!quitWorking)
{
delegate myWork;
lock(_queue)
{
if(_queue.Count > 1)
myWork = _queue.Dequeue();
}
myWork();
}
}
}
Is that possible not not block winForm using WaitHandle.WaitAll(waitHandles) but just set another thread which will fire when get complate signal from WaitHandle.WaitAll?
I would not use WaitHandle.WaitAll. There are a couple of problems with this approach.
There is a 64 handle limit.
It cannot be used on an STA thread.
It promotes patterns that depend on the creation of multiple WaitHandle instances which obviously consume resource.
Instead, I typically use the CountdownEvent class when I want to wait on multiple events. Now, the problem you will have with that is that it still requires you to call Wait on some thread which is exactly what you are trying to avoid. The standard mechanism to avoid making a blocking call is to use the ThreadPool.RegisterWaitForSingleObject method. But, unfortunately that takes a WaitHandle and CountdownEvent does not inherit from that class.
The solution is to create your own CountdownWaitHandle class that can be used in the ThreadPool.RegisterWaitForSingleObject method. This approach will allow you to specify a callback delegate that will be executed once the WaitHandle is signaled.
Here is the most basic implemenation for the CountdownWaitHandle class. You will have to add all of the necessary harding code yourself, but this will get you started.
public class CountdownWaitHandle : WaitHandle
{
private int m_Count = 0;
private ManualResetEvent m_Event = new ManualResetEvent(false);
public CountdownWaitHandle(int initialCount)
{
m_Count = initialCount;
}
public void AddCount()
{
Interlocked.Increment(ref m_Count);
}
public void Signal()
{
if (Interlocked.Decrement(ref m_Count) == 0)
{
m_Event.Set();
}
}
public override bool WaitOne()
{
return m_Event.WaitOne();
}
}
The idea here is that instead of using many different WaitHandle instances you use a single CountdownWaitHandle instance. Initialize the instance with the desired count and then call Signal to decrement the count. Once the count gets to zero the WaitHandle will go into the signaled state. So instead of calling Set on multiple WaitHandle instances and blocking with WaitHandle.WaitAll you now call Signal on this one instance and block by calling WaitOne. And again, you can push off the blocking call to the thread pool by using TheadPool.RegisterWaitForSingleObject which will invoke a callback when the WaitHandle is signaled.
You can call WaitAll in a background thread, then call BeginInvoke to move back to the UI thread.
Have a look at ManualResetEvent. Using this you can set the event when your thread has finished, and any other thread can either wait on this event, or check to see if it is in the signalled state.
ManualResetEvent ev = new ManualReserEvent();
while(Users["user428547"].AcceptanceRate == 0)
{
// this might take a long time
};
ev.Set(); // done, he accepted an answer.
Perhaps you could start another thread yourself, and call WaitHandle.WaitAll yourself on that thread? If you are not starting too many other threads, this should work fine.