Thread killing by name - c#

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

Related

Execute Task.Run on main thread

I am using monotouch/Xamarin for an iOS app.
The documentation for Task.Run states:
Queues the specified work to run on the ThreadPool and returns a task
handle for that work.
Which essentially indicates that it could run on any thread ThreadPool.
I want to do something like:
Task.Run(async () => await PerformTask());
but have it run on the main thread. Normally I would write it using BeginInvokeOnMainThread as follows:
BeginInvokeOnMainThread(async () => await PerformTask());
But I am doing this in shared code and do not want to use iOS specific calls. Is there a way for me to tell Task.Run() to invoke the action on the main thread?
If you want to run PerformTask in the current thread, instead of a thread pool thread, you simply need to not call Task.Run. Just use:
PerformTask();
and you're done. If you want to only continue executing the rest of the method when that task is done, then await it:
await PerformTask();
There is no reason to call Task.Run here for you, nor is there any reason to create a lambda that awaits the method for no particular reason (you could just call it directly if you wanted to start it from a thread pool thread).
If you want to run a task from the main thread you could use TaskSchedluer's method FromCurrentSynchronizationContext().
Task t = new Task(() =>
{
...
});
t.Start(TaskScheduler.FromCurrentSynchronizationContext());
This can be useful sometimes. However, if you want to use this technique to bypass thread checks (for example, modifying properties of form controls in a windows app), you should rethink your design. Use tasks for calculations or other non-UI operations and update the UI from the main thread.
Have a look at MainQueue.cs: https://gist.github.com/gering/0aa9750d3c7d14b856d0ed2ba98374a8
It is for Xamarin Forms applications. You have to call Init() from main thread once, but then you are able to ensure execution on main thread.

How End a thread conformation

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

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.

How to make a child thread sleep without freezing UI thread in WPF application?

I have a WPF application and I have individual threads running to accomplish tasks and I would like to have the current thread to go to sleep something like,
Thread.CurrentThread.Sleep(10000)
I do see it in Java but not in C#. I do know that I only have only one UI thread, so if I use Thread.Sleep(10000) my UI thread will be block. I am using async and await from .NET 4.5.
var words = await Task.Factory.StartNew(() => {
StringMgr.TextToUniqueWords(File.ReadAllText(filename));
// I want to be able to sleep this thread for 10 seconds, without the UI freezing
});
So how do I put a child thread to sleep without freezing the UI thread in a WPF application?
Thanks!
Since you're already using async, you can just do it the asynchronous way:
var words = await Task.Run(async () =>
{
StringMgr.TextToUniqueWords(File.ReadAllText(filename));
await Task.Delay(TimeSpan.FromSeconds(10));
});
However, I suspect that sleeping is the wrong solution for the actual problem you're trying to solve. If you'd like to post another question with your actual problem, you may find a better solution.
Have you tried it? Sleeping thread inside a Task won't freeze your GUI but it will make the current background thread to go in sleep mode and your UI will remain responsive always -
Task.Factory.StartNew(() =>
{
Thread.Sleep(5000000); // this line won't make UI freeze.
});
Thread.Sleep(5000000); // But this will certainly do.

Sleep task (System.Threading.Tasks)

I need to create thread which will replace photo in Windows Forms window, than waits for ~1second and restore the previous photo.
I thought that the following code:
TaskScheduler ui = TaskScheduler.FromCurrentSynchronizationContext();
var task = Task.Factory.StartNew(() =>
{
pic.Image = Properties.Resources.NEXT;
Thread.Sleep(1000);
pic.Image = Properties.Resources.PREV;
}, CancellationToken.None, TaskCreationOptions.LongRunning, ui)
do the job, but unfortunately doesn't. It freezes main UI thread.
That's because it's not guaranteed that there is one thread per one task. One thread can be used for processing several tasks.
Even TaskCreationOptions.LongRunning option can't help.
How I can fix it?
Thread.Sleep is a synchronous delay. If you want an asynchronous delay then use Task.Delay.
In C# 5, which is at present in beta release, you can simply say
await Task.Delay(whatever);
in an asynchronous method, and the method will automatically pick up where it left off.
If you are not using C# 5 then you can "manually" set whatever code you want to be the continuation of the delay yourself.
When you pass a new TaskScheduler that is from the current synchronization context, you actually telling the task to run on the UI thread. You actually want to do that, so you can update the UI component, however you don't want to sleep on that thread, since it will block.
This is a good example of when .ContinueWith is ideal:
TaskScheduler ui = TaskScheduler.FromCurrentSynchronizationContext();
var task = Task.Factory.StartNew(() =>
{
pic.Image = Properties.Resources.NEXT;
},
CancellationToken.None,
TaskCreationOptions.None,
ui);
task.ContinueWith(t => Thread.Sleep(1000), TaskScheduler.Default)
.ContinueWith(t =>
{
pic.Image = Properties.Resources.Prev;
}, ui);
EDIT (Removed some stuff and added this):
What happens is that we're blocking the UI thread for only enough time to update pic.Image. By specifying the TaskScheduler, you're telling it what thread to run the task on. It's important to know that the relationship between Tasks and Threads is not 1:1. In fact, you can have 1000 tasks running on relatively few threads, 10 or less even, it all depends on the amount of work each task has. Do not assume each task you create will run on a separate thread. The CLR does a great job of balancing performance automatically for you.
Now, you don't have to use the default TaskScheduler, as you've seen. When you pass the UI TaskScheduler, that is TaskScheduler.FromCurrentSynchronizationContext(), it uses the UI thread instead of the thread pool, as TaskScheduler.Default does.
Keeping this in mind, let's review the code again:
var task = Task.Factory.StartNew(() =>
{
pic.Image = Properties.Resources.NEXT;
},
CancellationToken.None,
TaskCreationOptions.None,
ui);
Here, we're creating and starting a task that will run on the UI thread, that will update the Image property of pic with your resource. While it does this, the UI will be unresponsive. Fortunately, this is a likely a very fast operation, and the user won't even notice.
task.ContinueWith(t => Thread.Sleep(1000), TaskScheduler.Default)
.ContinueWith(t =>
{
pic.Image = Properties.Resources.Prev;
}, ui);
With this code, we're calling the ContinueWith method. It does exactly what it sounds like. It returns a new Task object that will execute the lambda parameter when it runs. It will be started when the task has either completed, faulted or been cancelled. You can control when it will run by passing in TaskContinuationOptions. However, we're also passing a different task scheduler as we did before. This is the default task scheduler that will execute a task on a thread pool thread, thus, NOT blocking the UI. This task could run for hours and your UI will stay responsive (don't let it), because it's a separate thread from the UI thread that you are interacting with.
We've also called ContinueWith on the tasks we've set to run on the default task scheduler. This is the task that will update the image on the UI thread again, since we've passed that same UI task scheduler to the executing task. Once the threadpool task has finished, it will call this one on the UI thread, blocking it for a very short period of time while the image is updated.
You should be using a Timer to perform a UI task at some point in the future. Just set it to run once, and with a 1 second interval. Put the UI code in the tick event and then set it off.
If you really wanted to use tasks, you'd want to have the other task not run in the UI thread but rather in a background threat (i.e. just a regular StartNew task) and then use the Control.Invoke inside of the task to run a command on the UI thread. The problem here is that is' band-aid-ing the underlying problem of starting a task just to have it sleep. Better to just have the code not even execute in the first place for the full second.

Categories

Resources