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.
Related
I have a problem how to await async methods in WPF life-cycle methods (with Caliburn-Micro framework) (eg. OnActivate, OnInitialized, OnExit - which is bound directly to Application.Exit event)
This article exactly describes my problem: http://mark.mymonster.nl/2013/07/10/donrsquot-make-your-application-lifetime-events-async-void (now I am thinking of using the solution from this article, but seems like a bit overkill for the first look)
I need to await some async methods in my OnExit hanlder so I have it as async. And it works. Kind of.
I do not understand why??, but on calling Application.Exit event it somehow waits until the method is completed, even if the handler is async void. Can you explain please how this is possible? And is this safe? Or is it just coicidence? Async void should be used only for Top-Level events, is this that case?
I looked in the code of System. And the binding looks like this:
public event EventHandler Exit
{
add
{
XcpImports.CheckThread();
this.AddEventListener(DependencyProperty.RegisterCoreProperty(20053U, (Type) null), (Delegate) value);
}
remove
{
XcpImports.CheckThread();
this.RemoveEventListener(DependencyProperty.RegisterCoreProperty(20053U, (Type) null), (Delegate) value);
}
}
which is really cryptic and I cannot see what really happens in .net framework by calling this event.
What is as well strange, that calling await Task.Delay(1) in the handler causes DeadLock when I do not use ConfigureAwait(false). So I would say there is somewhere .Wait() used deep in .net code.
Note: when I make OnActivate, OnInitialized handlers async, as expected, page is not waiting till handler completes.
Thx for your answeres!
It is theoretically possible for a framework to detect the use of async void and wait until the async void method returns. I describe the details in my article on SynchronizationContext. AFAIK, ASP.NET is the only built-in framework that will wait on async void handlers.
WPF does not have any special treatment for async void methods. So the fact that your exit handler is completing is just coincidence. I suspect that the operations you await are either already complete or extremely fast, which allows your handler to complete synchronously.
That said, I do not recommend the solution in the article you referenced. Instead, handle the window's Closing event, kick off whatever asynchronous saving you need to do, and cancel the close command (and also consider hiding the window immediately). When the asynchronous operation is complete, then close the window again (and allow it to close this time). I use this pattern for doing asynchronous window-level "close" animations.
I'm unable to repro the deadlock you describe. I created a new .NET 4.5 WPF application and added an exit handler as such:
private async void Application_Exit(object sender, ExitEventArgs e)
{
await Task.Delay(1);
}
but did not observe a deadlock. In fact, even with using Task.Yield, nothing after the await is ever executed, which is what I would expect.
I have a main thread that starts a few worker threads through a class that implements the Event-based Asynchronous Pattern (http://msdn.microsoft.com/en-us/library/ms228969.aspx). Unfortunately, as soon as the main thread is done setting up the worker threads, it exits.
I want the main thread to wait indefinitely until the anEventHandler method is called, then process that method. The asyncevents listen for events indefinitely until canceled, so they might call the anEventHandler method multiple times before completing.
NOTE: There is no related GUI, I'm just using this pattern.
public static void Main(String[] args) {
AsyncEventClass asyncevent = new AsyncEventClass();
// setup event handling
asyncevent.Events += new EventsHandler(anEventHandler);
// start event monitoring threads
asyncevent.monitorAsync(1);
asyncevent.monitorAsync(2);
asyncevent.monitorAsync(3);
System.Console.WriteLine("The main thread now ends. :(");
}
All the examples online use System.Console.ReadLine(), but that seems like a terrible idea in production code.
You can use a simple AutoResetEvent which you wait for in the main method, and set in the event handler.
If you want to wait for a specific amount of times that the eventhandler is called, I guess you can keep a counter, and set the auto-reset-event only when you reach a certain threshold.
I ended up putting all of the IAsyncResutl objects returned by calling WorkerEventHandler.BeginInvoke into a list, and then exposing that list to the Main method. There, I setup all the asyncevents I need to listen for, then use WaitHandle.WaitAll to wait for the events to complete.
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())
{...}
I have read that I can use asynchronous call with polling especially when the caller thread serves the GUI. I cannot see how because:
while(AsyncResult_.IsCompleted==false) //this stops the GUI thread
{
}
So how it come it should be good for this purpose? I needed to update my GUI status bar everytime deamon thread did some progress..
You are correct in your while loop stopping the GUI thread, when doing it like that, you don't want to do that.
If you need to poll, it would be better is to set up a Timer, and check whether the work has completed when the timer fires. The Timer can have a small resolution without problems (100 ms for instance), as long as you dont do much work during each tick.
However, I think you would be even better off by using a callback, so you do not need to poll and get notified as soon as your workload is done.
The point of async polling is that you can do other things in between checking IsCompleted — such as servicing GUI events. You could set a timer, for example, to trigger an event several times per second to check whether your asynchronous operation is finished, and use the normal GUI event loop to service those events together with all the other events your GUI receives. That way, your GUI remains responsive, and shortly after the async operation finishes, your timer event handler will notice it.
I was having the same trouble with an old API exposing BeginExecute() and EndExecute(). BeginExecute() started asynchrounous operation and then went silent until it finished executing to the end. But I was needed to update intermediate state of the execution progress in real-time.
So I came up with the following solution:
var asyncResult = command.BeginExecute();
while (!asyncResult.IsCompleted)
{
if (command.State != OldState)
{
progress.Report(newState);
}
// Key piece in this polling loop.
await Dispatcher.Yield(DispatcherPriority.ApplicationIdle);
}
command.EndExecute(asyncResult);
At first I have used
await Task.Yield();
But then I found out that in WPF it won't return the control to GUI, because this loop will have higher priority. That is why I switched to this instruction:
await Dispatcher.Yield(DispatcherPriority.ApplicationIdle);
So now GUI will check and update progress only when it has nothing else to do :)
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) !!).