Sorry i know this is a beginner question but i did some googling and none of the answers really helped me.
Basically i have an async method that returns a Task. It is results from an API but i’m not sure that’s important.
Anyway on button click i will make the API call. What i would like to do is some execution when the task completes. In the meantime i cannot wait for the task to completed and hold up the main thread.
So for example this is essentially what i would like to have happen.
You have a few choices here. I don’t like using lambdas for event handlers, it’s easier to show you what’s happening if it’s a separate method.
One way you could do this is to use a feature of tasks called “continuations”. To do this, you call ContinueWith()
on the task that does the search. This takes a delegate that will be executed after the task completes. You also have the option to specify a “scheduler”, which is important here because it’s a way you can tell your framework “I want the continuation to happen on the UI thread.” It’d look like this:
The task will run asynchronously, then the “continue with” part will run on the UI thread.
async/await
is a shortcut syntax for this. It’s more complicated than people let on, but makes for an easy example. It’d look like this:
It’s sort of magic. The await
tells the UI thread you’re done for now, and it goes about its business. When the task completes, it pokes the UI thread and the next time the UI isn’t busy execution continues on the line after the await
. Generally async void
is frowned upon, but it has to exist for event handlers. Read up on async/await
for a few days before using it too promiscuously.
I assume you are using WPF, since you didnt specify. After the original Task is completed, you can make the WPF Dispatcher instance run another lambda in the UI thread that basically takes the result from the completed Task and updates the Textbox for you. This will be executed only when the Task completes and the UI Thread wont be locked while so.
Hope that helps
If you mark the event handler async and await the Task then the handler will resume on the UI thread. No need to explicitly invoke the Dispatcher.
If you want a move MVVM way to do this, you can look at this Microsoft documentation. There are also some libraries that provide this class for you, such as Nito.Mvvm.Async.