How End a thread conformation - c#

So I'm still fairly new to C#.
So far I would like to know how to check if a thread has ended. I know that i can put a bool at the end of the method the thread uses and use that to determine if the thread ends.. but i dont want to do that, mainly because i want to learn the right way
so far I have this.
Thread testThreadd = new Thread(Testmethod);
testThreadd.Start();
testThreadd.Join();
I read about the thread.join(); class. To my understanding, that class only prevents any code after that from executing.. Please help.
thanks

Well there are different ways that give different results
1 ) Wait until the work has finished. This is exactly what you've got with your code already. You'll start a thread and then wait for that thread to finish before continuing execution.
thread.Start();
thread.Join();
2) thread.ThreadState will tell you whether or not the thread has finished. In a basic scenario you could do the following. This would allow you to check the current thread state at any point in your code where you've got access to the state.
if(thread.ThreadState != ThreadState.Running){
// Thread has stopped
}
3) Using an event. A lot of Async examples will start some work and then trigger an event once the work has been completed. In this way you can sit watching for an event and respond once the work has completed. A usage example may look like the WebClient class
WebClient client = new WebClient();
client.DownloadFileCompleted += new
AsyncCompletedEventHandler(client_DownloadFileCompleted);

You can check for Thread.IsAlive property.

What you tried is a right way to wait for a thread to be done. But:
Thread.Join() is a function of Thread class.
Calling Join() function of a thread instance (in your sample testThreadd) will make the current thread to wait until testThreadd finishes it's job. Current thread is the thread which is calling testThreadd.Join()

In addition to the supplied answers, these days, the most used method would be by using Tasks. Besides having all the Wait and IsCompleted possibilities, these have the added advantage of having a ContinueWith method
start a task
var task = Task.Run((Action)TestMethod);
check completed
if (task.IsCompleted) { }
wait for task to finish (same as thread.sleep)
task.Wait();
setting a continuewith (additional task to be started after the task finishes)
var task = new Task((Action)TestMethod);
task.ContinueWith(t => MessageBox.Show("Finished"));
task.Start();
and combined, waiting for the continued task to finish (which automatically means, the first task is finished)
var task = new Task((Action)TestMethod);
var continuedtask = task.ContinueWith(t => MessageBox.Show("Finished"));
task.Start();
continuedtask.Wait();

You could use a BackgroundWorker instead of manually starting a new thread. It raises the RunWorkerCompleted event if its work is done (or if an exception occurs).

Related

Periodically check to see if all threads have completed

I have an multithreaded application and I want to be able to use a timer to periodically check to see if all threads have finished before starting a new one, ie:
var checkStatusTimer = new System.Threading.Timer(new TimerCallback(CheckThreads), null, 10000, 10000);
This is as far as I've come. What would need to go in the CheckThreads Method to check to see if they're done? I was thinking of something along the lines of a function that checks them like:
foreach (Thread thread in Threads)
{
Thread t = thread;
if (t.ThreadState != ThreadState.Stopped)
return false;
}
Am I on the right track? is this the correct way to go about this? Or should I use a System.Timers.Timer instead? Also, the function form within I want to do this periodic check is static. Any help would be appreciated.
Use Task instead of Thread. Then, you can create a combined task:
Task[] tasks = ...; //You provide this
Task combined = Task.WhenAll(tasks);
Now you can check for completion: combined.IsCompleted. You can also Wait and await that task.
Thread is a legacy API that is rarely a good idea to use.
#usr's task-based approach is best, but if you must rely on threads, then I suggest that as each thread is completes it invokes a method that removes the thread from your Threads collection. Then all you have to do in your timer callback is to check the count of the collection. Relying on ThreadState is not advisable.

Thread killing by name

I have a problem with my thread...
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate {}));
Thread.Sleep(90);
It starts and works fine but like forever, and I don't want to run this thread forever.
Is there possible way to give to this thread a name so I can kill it by name in any time I want?
I tried kill it with:
Dispatcher.CurrentDispatcher.thread.Abort();
but it kill's whole app...
Basically...
I have a custom combo in my WPF app... this thread is in while loop, when I open the combo starts a loop while(!context.IsClosed) but when its closed, it still runs in background
Your understanding of multithreading approach is completely wrong.
First of all, no, there is no way to give a name to your thread being invoked in such way.
Second, killing a thread is a completely wrong approach in the situations like this, there is easy way to do such things: CancellationToken. You can use some overloads for the Dispatcher.Invoke with them (either using the start timeout or not), like this:
Dispatcher.Invoke Method (Action, DispatcherPriority, CancellationToken):
CancellationTokenSource s = new CancellationTokenSource();
Dispatcher.CurrentDispatcher.Invoke(() => YourMethodHere(), DispatcherPriority.Background, s.Token);
Thread.Sleep(90);
s.Cancel();
After calling the Cancel method the .NET will automatically stop your thread.
Second possible approach, as written in comments, is to use TPL for this, without using the Thread creation, something like this (code from MSDN article about SynchronizationContext):
// This TaskScheduler captures SynchronizationContext.Current.
TaskScheduler taskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
// Start a new task (this uses the default TaskScheduler,
// so it will run on a ThreadPool thread).
Task.Factory.StartNew(() =>
{
// We are running on a ThreadPool thread here.
// Do some work.
// Report progress to the UI.
Task reportProgressTask = Task.Factory.StartNew(() =>
{
// We are running on the UI thread here.
// Update the UI with our progress.
},
s.Token,
TaskCreationOptions.None,
taskScheduler);
reportProgressTask.Wait();
// Do more work.
});

End a thread conformation

So I'm still fairly new to C#. Im learning about threads.
So far I would like to know how to check if a thread has ended. I know that i can put a bool at the end of the method the thread uses and use that to determine if the thread ends.. but i dont want to do that, mainly because i want to learn the right way
so far I have this.
Thread testThreadd = new Thread(Testmethod);
testThreadd.Start();
testThreadd.Join();
I read about the thread.join(); class. To my understanding, that class only prevents any code after that from executing.. Please help
Well there are different ways that give different results
1 ) Wait until the work has finished. This is exactly what you've got with your code already. You'll start a thread and then wait for that thread to finish before continuing execution.
thread.Start();
thread.Join();
2) thread.ThreadState will tell you whether or not the thread has finished. In a basic scenario you could do the following. This would allow you to check the current thread state at any point in your code where you've got access to the state.
if(thread.ThreadState != ThreadState.Running){
// Thread has stopped
}
3) Using an event. A lot of Async examples will start some work and then trigger an event once the work has been completed. In this way you can sit watching for an event and respond once the work has completed. A usage example may look like the WebClient class
WebClient client = new WebClient();
client.DownloadFileCompleted += new AsyncCompletedEventHandler(client_DownloadFileCompleted);
Thread.Join() Blocks the thread you call it on until the thread you have called Join() on returns. Extending the example you have above:
Thread testThreadd = new Thread(Testmethod);
testThreadd.Start();
testThreadd.Join();
//Do more stuff here. This stuff will not start until testThreadd has completed its work.
you can do this
public partial class MainWindow : Window
{
Thread testThreadd;
public MainWindow()
{
InitializeComponent();
testThreadd = new Thread(Testmethod);
testThreadd.Start();
testThreadd.Join();
}
public void Testmethod()
{
// begining your treatement
// Ending your treatement
this.testThreadd.Abort();
}
}
Thread.Join method pauses current thread execution until second thread completes. It serves for thread synchronization and it's well enough indicator.
Otherwise, you should use Thread.IsAlive property to check if thread is running while not interrupting current thread. This property covers any state between Thread.Start and the end of the thread.

C# worker thread with event driven work and no shut down

Here's what I woulld like to do:
Create a worker thread in my main thread (which controls the UI).
The worker thread keeps running until shut down by the main thread (which only happens when the entire application is shut down).
The main thread listens for keyup, but sends an event to the worker thread to process the keyup asynchronously (to avoid blocking the UI).
The worker thread updates the UI when the keyup has been handled.
So far I've just been creating a new thread every time there is a keyup, but it seems there is just too much overhead this way.
As far as I can tell, I should use the BackgroundWorker class, but the examples I've seen seems to start a background worker, continue with non-blocked UI in the main thread and update UI from the BackgroundWorker when it's finished - i.e. exactly the same as I'm already doing.
How to make it so the worker thread keeps running and sleep when there is no work to be done?
While Zaches answer is completely valid (and an approach I used for some time) I've stumbled upon what I think is a more elegant solution using Dispatcher:
Create the worker thread:
Dispatcher _workerDispatcher;
Thread _workerThread = new Thread(new ThreadStart(() =>
{
_workerDispatcher = Dispatcher.CurrentDispatcher; // Required to create the dispatcher
Dispatcher.Run(); // Keeps thread alive and creates a queue for work
});
_workerThread.Start();
Put work into the worker thread (from main thread or another thread):
// Synchronous work
_workerDispatcher.Invoke(() =>
{
// Do stuff
});
// Asynchronous work (makes most sense for background work)
_workerDispatcher.BeginInvoke(() =>
{
// Do stuff
});
Shut down the worker thread:
_workerDispatcher.InvokeShutdown();
_workerThread.Join(); // Wait for thread to shut down
I'm using new Thread() because I need to set apartment state, but you can also use tasks created using Task.Run() and Task.Factory.StartNew().
I'm not 100% certain that it's necessary to call thread.Join(), but I'd rather be certain that the thread has been shut down. If you're using a Task call task.Wait() instead.
Another way to get the Dispatcher is to call Dispatcher.FromThread(thread), but it's important to note that a Dispatcher is NOT created until CurrentDispatcher has been used (even if you don't use the reference later).
A downside of this approach is that it can't be used to have multiple threads pick items out of a queue and do work - for that you will have to use the producer/consumer approached described in Zaches answer. The dispatcher approach allows you to queue up work in a specific thead.
Why don't you just use the Task Parallel Library?
Create a new task whenever you detect the KeyUp event, and let TPL worry about creating new threads. Since it uses the thread pool, a new thread will not be created every time an event is fired.
The problem you are having is called the Producer/Consumer problem. And you can solve it easily using any of the ConcurrentCollections available.
Try something like this:
var queue = new ConcurrentQueue<string>();
var consume = true;
var producer = Task.Run(() =>
{
var input = Console.ReadLine();
while(!string.IsNullOrEmpty(input)
{
queue.Enqueue(input);
input = Console.ReadLine();
}
});
var consumer = Task.Run(() =>
{
while(consume) //So we can stop the consumer
{
while(!queue.IsEmpty) //So we empty the queue before stopping
{
stringres;
if(queue.TryDequeue(out res)) Console.WriteLine(res);
}
}
});
await producer;
consume = false;
await consumer;
Try using the Task Pattern Library instead of manually starting up threads. It is your friend.

Last thread of a multithreaded application

I have a c# console application which has some threads to do some work (download a file).
each thread may exit the application at any time any where in application, but I'll show a proper message on console. It's possible to track them but it doesn't make sense to me. I want simply check thread count or something like that to find out which one is the last thread and do something when it is exiting.
What's the best practice to do so ?
pseudo code:
if (lastThread)
{
cleanUp();
Console.ReadLine();
}
Thanks
This is one place where using the new Task Parallel Library can make life much easier. Instead of creating threads, and spinning work up on the thread, you can use multiple tasks:
var task1 = Task.Factory.StartNew( () => DoTaskOneWork() );
var task2 = Task.Factory.StartNew( () => DoTaskTwoWork() );
var task3 = Task.Factory.StartNew( () => DoTaskThreeWork() );
// Block until all tasks are done
Task.WaitAll(new[] {task1, task2, task3} );
cleanUp(); // Do your cleanup
If the "tasks" are just downloading a bunch of individual files, you could even make this simpler using PLINQ:
var fileUrls = GetListOfUrlsToDownload();
fileUrls.AsParallel().ForAll( fileUrl => DownloadAndProcessFile(fileUrl) );
cleanUp(); // Do your cleanup
A design where you lose track of your threads is not ideal.
Depending on how you spawn them it ought to be possible to track the status of each by associating some per-thread signalable object, then WaitAll on those signalable objects.
Each signalable object in turn should get signaled as its thread exits. When they are all signaled, you know the threads are all dead and you close down clean. You have to make sure that abnormal conditions in your threads do not result in that thread's associated signalable object remaining unset, or your WaitAll will never return. This means exceptions typically - could use try...finally to ensure the objects get signaled.
Your new pseudocode is
foreach (workitem in list of work)
start up thread associated with a ManualResetEvent or similar
WaitAll for all events to be signalled
cleanup
Your main thread should join with all your worker threads and block while they are running. Then when all threads are complete it performs the cleanup code and then quits.
Alternatively you can use a WaitHandle such as as a ManualResetEvent per thread and wait for all of them to be signalled.

Categories

Resources