I am creating a new thread to call a function in it.
Thread th = new Thread(My_Function);
th.start();
I wanna do something on completion of this thread execution.
Is there any way of doing this ?
At least two possible solutions:
BackgroundWorker
Use a BackgroundWorker to execute your code, and use the RunWorkerCompleted event to execute the code that is run after completion.
A BackgroundWorker wraps the event based asynchronous pattern into a very easy to use mechanism, complete with progress reporting and cancellation. See this BackgroundWorker tutorial and this SO answer .
Tasks (.NET 4.0 and above)
Use a Task object, and use the ContinueWith method to define the code that needs to be executed after completion of the first task.
You can use something such
if(th.isAlive())
{...}
Related
I'm working on some old code that runs on custom background thread. this thread uses the thread class and passes it a thread delegate i.e. an action.
_thread = new Thread(() => processData());
i need to call some newer functions that return task so do i just do
myfunc().GetAwaiter().GetResult();
or is there some other way? because since it is a custom thread, i don't think if it is really doing anything this time. how can i call async await from. the custom thread so that it is utilized properly?
If you want to continue using your custom Thread, then yes, it has to block on asynchronous code. GetAwaiter().GetResult() is probably your best bet for that.
or is there some other way?
Yes. If you can replace your custom Thread with a thread pool thread, then you can use Task.Run instead of Thread, and then you can use the more natural await instead of GetAwaiter().GetResult(). Most custom threads can be replaced by thread pool threads, but this is not always the case.
I need to wait for an event to finish before continuing.
Here is my code:
foreach (KeyValuePair<string, Stream> pair in this.XMLCollection)
{
...
this.eventAggregator.GetEvent<LogToApplicationEvent>().Publish(credentials);
//wait
...
}
Before continuing I need to wait for "login" event to execute complately.
I tried using Task.Factory, but it did not work for me, or I cant use it right...
This code is on presenter, but the event updates the main UI.
//publish
public virtual void Publish(TPayload payload)
{
base.InternalPublish(payload);
}
At least two possible solutions:
BackgroundWorker
Use a BackgroundWorker to execute your code, and use the RunWorkerCompleted event to execute the code that is run after completion.
A BackgroundWorker wraps the event based asynchronous pattern into a very easy to use mechanism, complete with progress reporting and cancellation. See this BackgroundWorker tutorial and this SO answer .
Tasks (.NET 4.0 and above)
Use a Task object, and use the ContinueWith method to define the code that needs to be executed after completion of the first task.
Event Aggregator publishing and subscribing event pattern is synchronous. You need not to worry about it.
So, it won't resume until its subscribers are finished executing its delegates.
Assumption - You are using inbuilt Event Aggregator class provided by Microsoft.
I am using WPF and DelegateCommand from PRISM and have the following problem:
I start an async operation like:
public async void ProgramDevice()
{
var result = await FirmwareLoader.DownloadFirmwareAsync();
}
Inside this method an event is fired which I registered to and should update my DelegateCommand so it can't be executed:
//UiCommand is of type DelegateCommand
Engine.IsProgrammedChanged +=
(s, e) => Dispatcher.Invoke(() => UiCommand.RaiseCanExecuteChanged());
Now I have the problem, that the RaiseCanExecuteChanged causes a deadlock (I checked and the Dispatcher.Invoke does not cause it, because when I e.g. show a MessageBox instead it works fine).
Am I doing something wrong or how can I work around this problem?
I see you've already solved your problem, but I thought I'd give a more general solution that will help you prevent such deadlocks in the future.
In your case, you could easily avoid this deadlock by using ConfigureAwait like this:
var result = await FirmwareLoader.DownloadFirmwareAsync().ConfigureAwait(false);
What this does is allows the continuation to be performed on a different thread than the original. Doing so is not always possible, since a lot of times you need the continuation to be performed on the UI thread, but for this question I don't believe that's the case. So basically, the best practice is to always use ConfigureAwait(false) unless you need to resume execution from the original thread.
This article explains in detail why these kind of deadlocks happen and how to avoid them. Another recommended read is Best Practices in Asynchronous Programming.
Found the problem:
It was not the RaiseCanExecuteChanged, but the actual CanExecute which is triggered by it. In there I had an AsyncLock which waited for the programming task to be finished, before returning the value I use to descide if UiCommand can be executed --> deadlock as the programming task triggered it...
I solved it by simple using the "sync" property (which does not use the lock and just returns the current value/stat) of the value I need.
Am I doing something wrong or how can I work around this problem?
Method Dispatcher.Invoke blocks working thread until UI thread makes all updates
UI thread uses some resources locked by working thread (through RaiseCanExecuteChanged -> CanExecute method chain in the above code) and blocks
Deadlock since worker thread waits for UI thread to finish update and UI thread waits worker thread to release locked resources
A possible way to ensure no deadlocks is to asynchronously invoke updates on UI thread using Dispatcher.BeginInvoke.
//UiCommand is of type DelegateCommand
Engine.IsProgrammedChanged +=
(s, e) => Dispatcher.BeginInvoke(() => UiCommand.RaiseCanExecuteChanged());
This way UI thread will wait for a moment when working thread releases locked resources and then will update. But there will be no deadlock.
Is there an elegant way to know when a worker thread is done executing so I can access resources it produced?
For example if the worker thread queried a list of SQL Servers using
ServersSqlDataSourceEnumerator.Instance.GetDataSources();
and saved the result in a DataTable variable, what mechanism can I use to know when this DataTable variable has been populated/is available. I don't want to poll ThreadState; it would be ideal to fire an event when it's done so I can perform actions with the result.
Thanks!
You can use a callback mechanism or block on an event to know of completion of an Async operation. See this page for the Asychronous Programming Model in .net - you can call BeginInvoke on any delegate to perform the action in an Async manner.
If you're using the BackgroundWorker type, you can subscribe to the RunWorkerCompleted event.
So fire an event :-P
You could also look at using an AutoResetEvent:
http://msdn.microsoft.com/en-us/library/system.threading.autoresetevent.aspx
What I do in this instance is get the WorkerThread to call a function after it has completed the work, which will invoke the the UI Thread, which can do the work in which you require.
E.g.
private void SetWorkerThreadToDoWork()
{
WorkerThread.Start();
}
private void MyWorkerThreadWork()
{
//This will be on the WorkerThread (called from WorkerThread.Start())
DoWorkFunc();
WorkComplete();
}
private void WorkComplete()
{
if(InvokeRequired == true)
{
//Do the invoke
}
else
{
//Check work done by worker thread
//e.g. ServersSqlDataSourceEnumerator.Instance.GetDataSources();
}
}
If it's a simple process you're using, I'd go for a BackgroundWorkerThread, this comes with it's own events that are fired when work is complete. But if you require to use a Thread, I would either look in to Asynchronous Callbacks or a similar route to that shown above.
You can check my answer on this SO thread
It uses a call back mechanism. When the async operation is done, it will fire the callback method where you can handle the processing that needs to be done post SQL execution.
Use a similar approach to be notified when the asynchronous operation is done.
Hope this helps :)
I don't program in C# but here's what I did with Delphi, maybe you can do it as well with C#.
I have a TThread descendant, and in the "destroy" event I send a message to its creator saying "hey I'm about to die !".
This way its parent (which is the main thread) creates a new one if it needs a new one. To be precise it launches a timer that, when fired, creates a new thread if a new one is needed (sites sucking time (lol) !!).
I'm working on a multi-threaded Silverlight application.
The application has two threads: Main/UI and a background working thread.
The UI thread should be able to kill the background thread, like so:
private Thread executionThread;
....
executionThread = new Thread(ExecuteStart);
executionThread.Start();
....
executionThread.Abort(); // when the user clicks "Stop"
The last line raises an Exception:
MethodAccessException: Attempt to access the method failed: System.Threading.Thread.Abort()
Any idea? why i cannot abort a thread in Silverlight?
Thanks,
Naimi
Rather than creating a Thread manually for this purpose you might want to consider using the BackgroundWorker class.
This class has built in functionality for cancelling the asynchronous operation when WorkerSupportsCancellation = true.
Have a look at this article on MSDN for a full example of how to use the BackgroundWorker in Silverlight.
It's documented, see Thread.Abort()
This member has a
SecurityCriticalAttribute attribute,
which restricts it to internal use by
the .NET Framework for Silverlight
class library. Application code that
uses this member throws a
MethodAccessException.
You could use a ManualResetEvent (a thread safe communication method) to signal the background thread to stop.
Example code in the background thread:
if (!shouldStop.WaitOne(0))
// you could also sleep 5 seconds by using 5000, but still be stopped
// after just 2 seconds by the other thread.
{
// do thread stuff
}
else
{
// do cleanup stuff and exit thread.
}
Since Silverlight code comes across the Internet, it is generally untrusted, and its execution is more restricted, as Davy pointed out.
Rather, implement a boolean exit flag in the class that is canonical for the background thread, so that you can raise this flag and use Thread.Join() instead.