I assume you want to do it asynchronously. (Synchronously, you would call
Thread.Join
, and that would be a blocking call for a calling thread. Not always, but in many cases it could defeat the purpose of threading, because the threads involved are not really executed in parallel during this blocking. :-))
So, the thread which is about to be complete should actively notify about it.
This should be some code in this thread itself. First of all, if this is a console application; and if you only need to print "Done". In this case, the solution is as simply as printing it in this very thread.
I don't to use your confusion to go away with such a simple but not very useful solution though. :-) In a more general case, you would need to do something in a loosely-coupled piece of code. In this case, you would need to get some notification. You only should understand that the notification will come in a separate thread (the one about to be complete) anyway. You will need to do something about it.
To provide a notification, I recommend to create a thread wrapper, define an event in the wrapper class, and add an event handler by any class using the wrapper.
class ThreadWrapper {
internal ThreadWrapper() {
Thread = new System.Threading.Thread(Body);
}
internal event System.EventHandler Complete;
internal void Start() { this.Thread.Start(); }
internal void Abort() { this.Thread.Abort(); }
void Body() {
if (this.SomeByRefParameter == null)
this.SomeByRefParameter = new System.Text.StringBuilder();
if (Complete != null)
Complete.Invoke(this, new System.EventHandler());
}
System.Threading.Thread Thread;
}
Please see my past answer on the techniques based on thread wrappers:
How to pass ref parameter to the thread[
^],
change paramters of thread (producer) after it started[
^].
Not, when you add an event handler, it will be called in the thread wrapped in the
ThreadWrapper
. But the handler was created in some other thread, it may use some members of other class created in another thread, which is not always possible. For example, if this other thread is a UI thread, you won't be able to use any UI members directly.
The very general mechanism is to delegate some method to be called in another thread (other then the thread calling an event handle). In general case, I described such mechanism in my article, complete with source code and usage samples:
Simple Blocking Queue for Thread Communication and Inter-thread Invocation[
^].
This method would allow to cross-invoke a call to another thread, which should be programmed in a certain way though. Everything is explained in my article, with samples.
With UI, such mechanism is already exists. Keep reading.
You cannot call anything related to UI from non-UI thread. Instead, you need to use the method
Invoke
or
BeginInvoke
of
System.Windows.Threading.Dispatcher
(for both Forms or WPF) or
System.Windows.Forms.Control
(Forms only).
You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[
^],
Problem with Treeview Scanner And MD5[
^].
See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[
^],
Control events not firing after enable disable + multithreading[
^].
—SA