I have following problem:
I want to check (C#) if a thread has finished execution, i.e. if the thread method has returned. What I do now is call Thread.Join(1), but this gives a 1 ms delay. Is there any way to simply check if a thread has finished. Inspecting Thread.ThreadState just seems too cumbersome.
Use the Thread.IsAlive flag. This is to give the thread status.
For a thread you have the myThread.IsAlive property. It is false if the thread method returned or the thread was aborted.
If you don't want to block the current thread by waiting/checking for the other running thread completion, you can
implement callback method like this.
Action onCompleted = () =>
{
//On complete action
};
var thread = new Thread(
() =>
{
try
{
// Do your work
}
finally
{
onCompleted();
}
});
thread.Start();
If you are dealing with controls that doesn't support cross-thread operation, then you have to invoke the callback method
this.Invoke(onCompleted);
You could fire an event from your thread when it finishes and subscribe to that.
Alternatively you can call Thread.Join() without any arguments:
Blocks the calling thread until a thread terminates, while continuing to perform standard COM and SendMessage pumping.
Thread.Join(1) will:
Blocks the calling thread until a thread terminates or the specified time elapses, while continuing to perform standard COM and SendMessage pumping.
In this case the specified time is 1 millisecond.
Use Thread.Join(TimeSpan.Zero) It will not block the caller and returns a value indicating whether the thread has completed its work. By the way, that is the standard way of testing all WaitHandle classes as well.
I use IsAlive extensively, unless I want to block the current execution (of the calling thread), in which case I just call Join() without a parameter. Now, be aware that IsAlive may return false if the target thread has not actually started execution yet for any reason.
Carlos Merighe.
It depends on how you want to use it. Using a Join is one way. Another way of doing it is let the thread notify the caller of the thread by using an event. For instance when you have your graphical user interface (GUI) thread that calls a process which runs for a while and needs to update the GUI when it finishes, you can use the event to do this. This website gives you an idea about how to work with events:
http://msdn.microsoft.com/en-us/library/aa645739%28VS.71%29.aspx
Remember that it will result in cross-threading operations and in case you want to update the GUI from another thread, you will have to use the Invoke method of the control which you want to update.
Take a look at BackgroundWorker Class, with the OnRunWorkerCompleted you can do it.
Related
I have a piece of code testing the GUI and threading behavior. I want to keep ProgressBar animation running (with IsIndeterminate="True") as I query the database and add a large number of rows (10K+) into the DataGrid. Even if I wrap the database and GUI code in Dispatcher.BeginInvoke, the ProgressBar animation would jerk as the DataGrid is being filled.
I would expect the ProgressBar animation would either freeze (if on GUI thread) or run smoothly (if on a separately thread), but I cannot understand why the animation is running jerkingly.
Please do not suggest BackgroundWorker, as I want to understand the problem in this question, and why BeginInvoke is not separating the threads. I simply loop through SqlDataReader and add to DataGrid as Item one by one instead of databinding to a source or a datatable.
// XAML
<Button Click="Button_Click"></Button>
<ProgressBar IsIndeterminate="True"></ProgressBar>
<DataGrid ... ></DataGrid>
// C#
private void Button_Click(object sendoer, RoutedEventArgs e)
{
this.Dispatcher.BeginInvoke(DispatcherPriority.Normal,(ThreadStart)delegate()
{
// Query database and update GUI (e.g. DataGrid)
});
}
The Dispatcher always executes code on the thread it is associated with (the UI thread in your case), regardless of whether you use Invoke or InvokeAsync (which is a convenient shorthand for BeginInvoke). So all the work regarding loading data from database and updating the DataGrid is done on UI thread, hence the animation is not smooth.
The difference between Invoke and InvokeAsync is that the former is executed synchronously, and the latter is executed asynchronously. What it means is that in the first case the calling thread will be suspended until the delegate has finished executing (i.e. it will be synchronized), whereas in the second case the thread will continue its execution without waiting for the delegate to finish. Let me try to point out this difference using examples.
Example I. The methods are called from the UI thread (as in your case)
Let's assume we only have one thread (the UI thread). Calling Invoke will not have any noticeable effect, since the delegate will be executed immediately and only then the execution will continue. So this:
Dispatcher.Invoke(() => DoSomeStuff());
DoSomeOtherStuff();
will have the same effect as this:
DoSomeStuff();
DoSomeOtherStuff();
Calling BeginInvoke however will have an effect such that the delegate will be scheduled to execute only after all scheduled tasks with higher priority (or already scheduled with the same priority) are executed. So in this case:
Dispatcher.InvokeAsync(() => DoSomeStuff());
DoSomeOtherStuff();
DoSomeOtherStuff() will be executed first, and DoSomeStuff() second. This is often used for example in event handlers where you need some code to be executed only after the event is completely handled (e.g. see this question).
Example II. The methods are called from a different thread
Let's assume we have two threads - the UI thread, and a worker thread. If we call Invoke from the worker thread:
Dispatcher.Invoke(() => DoSomeStuff());
DoSomeOtherStuff();
first DoSomeStuff() will be executed on UI thread, and then DoSomeOtherStuff() will be executed on worker thread. In case of InvokeAsync:
Dispatcher.InvokeAsync(() => DoSomeStuff());
DoSomeOtherStuff();
we only know that DoSomeStuff() will be executed on UI thread and DoSomeOtherStuff() will be executed on worker thread, but the order in which they will be executed is indeterminate*.
Usually Invoke is used when your delegate yields some result and you need it to continue execution on the worker thread (for example when you need to obtain a dependency property value). InvokeAsync on the other hand is usually used when the delegate does not yield any result (or the result is ignored), such as in your case - updating DataGrid does not yield any result worth waiting for so you can immediately continue to load the next batch of data.
I hope that sheds some light on the issue for you and you can see why the solution to "jerky UI" is to delegate heavy work to another thread and only use dispatcher to interact with UI. That's were suggestions to use BackgroundWorker or Task come from.
*Actually they probably will be executed simultaneously. What I meant was if for example both methods only print some text to console, the order of messages in the console is indeterminate.
Imagine you have some routine that registers as BeginInvoke to the ApplicationIdle, for example
Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, (Action)OffLoadWork);
Now in certain scenarios this OffLoadWork needs to be executed when doing a operation in the UI, for example on a button click, is it safe for me to call
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.ApplicationIdle, (Func<object>)(() =>
{
//do nothing just wait for the OffLoadWork to happen...
return null;
}));
or can it occur that my UI freezes, since I am in the middle of an UI Operation so when does it actually get Idle?
In my first test, it seemed to work but I just want to make sure that there isn't a way for it to freeze/block.
I think you are confusing DispatcherPriority.ApplicationIdle. Invoke is sync and can block your UI.
DispatcherPriority here as per the definition is the priority, relative to the other pending operations in the Dispatcher event queue, the specified method is invoked. So if your operation is the only one happening in the Dispatcher queue and triggered on UI thread it will block it till the time it does not return.
In the following code:
ThreadStart ts = new ThreadStart((MethodInvoker)delegate
{
executingThreads.Add(Thread.CurrentThread);
// work done here.
executingThreads.Remove(Thread.CurrentThread);
});
Thread t = new Thread(ts);
t.Start();
Perhaps you can see that I'd like to keep track of the threads that I start, so I can abort them when necessary.
But I worry that the Thread.CurrentThread is evaluated from the thread that creates the Thread t, and thus aborting it would not abort the spawned thread.
Aborting threads is never a good idea. If you are 100% positive that whatever task you are performing in the thread you want to abort will not corrupt any state information anywhere else then you can probably get away with it, but its best to avoid doing so even in those cases. There are better solutions like flagging the thread to stop, giving it a chance to clean up whatever mess it may leave behind.
Anyhow, answering your question, Thread.CurrentThread is executing in the method invoked when the new thread starts executing, therefore it will return the new thread, not the thread where the new thread was created (if that makes sense).
In the code you have given, Thread.CurrentThread is called in the context of the thread t and not its creator.
Also, aborting threads is morally equivalent to killing puppies.
To answer your question, and without comment on the wisdom of aborting a thread (I agree with previous commenters by the way), Thread.CurrentThread, as you have written it, will do what you are expecting to do - it will represent the thread that is currently invoking your delegate, not the thread that created and started the thread.
First of all I think it's a bad idea to abort threads, check the other answers/comments for the reasons. But I'll leave that aside for now.
Since your calls are inside a delegate they'll only be evaluated once the thread executes the content of that delegate. So the code works as you expect it to work and you get the thread on which the delegate executes, not the thread which created the delegate.
Of course your code isn't exception safe, you should probably put the remove into a finally clause.
executingThreads must be a thread safe collection, or you need to use locking.
Another way to keep track of the threads is to add the created thread to a collection from the creating thread, and then use the properties of that thread to check if the thread has already terminated. That way you don't have to rely on the thread keeping track itself. But this still doesn't fix the abortion problem.
When you call the BeginInvoke method on a Func delegates (or the Action delegates for that matter) in C#, does the runtime use the ThreadPool or spawn a new thread?
I'm almost certain that it'll use the ThreadPool as that'd be the logical thing to do but would appreciate it if someone could confirm this.
Thanks,
It uses the thread pool, definitely.
I'm blowed if I can find that documented anyway, mind you... this MSDN article indicates that any callback you specify will be executed on a thread-pool thread...
Here's some code to confirm it - but of course that doesn't confirm that it's guaranteed to happen that way...
using System;
using System.Threading;
public class Test
{
static void Main()
{
Action x = () =>
Console.WriteLine(Thread.CurrentThread.IsThreadPoolThread);
x(); // Synchronous; prints False
x.BeginInvoke(null, null); // On the thread-pool thread; prints True
Thread.Sleep(500); // Let the previous call finish
}
}
EDIT: As linked by Jeff below, this MSDN article confirms it:
If the BeginInvoke method is called,
the common language runtime (CLR)
queues the request and returns
immediately to the caller. The target
method is called asynchronously on a
thread from the thread pool.
"Executes the specified delegate asynchronously on the thread that the control's underlying handle was created on." - MSDN
The above is for Controls, but probably can be assumed to be the same functionality for Func's as well. BeginInvoke allows you to execute of your Func from another Thread, but won't create threads for you. So Jon Skeet would be correct. Unless you are creating threads for asynchronous execution I wouldn't even use this feature cause it won't buy you anything over just calling Invoke.
I've got a queue, which is basically the producer/consumer queue in the albahari.com
threading book, which takes an queue item off the queue, which is an action execution block off the queue and then calls a method to execute the actionlist within the queue item.
I can kill the queue easily enough by enqueing a null actionblock and block the main thread by doing a spin/wait with a thread.sleep() until the queue count goes to zero, and all the threads fall through the while !=null loop, thereby completing, but the method executing the last actionlist may still be executing the last thread.
Question is, is their anyway to detect if that method still has a thread executing it, like maybe using a Semaphore or counter with an Interlock to count the semaphore up at the beginning of the method and count it down at the end. So if it reaches zero, them I know its not threaded.
This is the implementing a destroy method on the interface, to close it down before calling dispose.
Use the Backgroundworker which has a completed event
If you start a thread like this:
System.Threading.Thread mythread = new System.Threading.Thread();
mythread.Start();
You can check:
mythread.IsAlive()
at any point to determine its status.
Use a PostSharp attribute on the method.