I'm running a Task in a new thread and want to wait for it to finish.
var a = "logic before the task starts";
await Task.Factory.StartNew(() => MyHugeFunction(_token), _token);
var b = "logic after the task is finished";
It worked perfectly until I started to dispatch inside of the thread with:
await Application.Current.Dispatcher.BeginInvoke(new Action(async () =>
{
SomeLogic();
}));
The task itself works, but the await for my running task isn't working anymore. As soon as I am dispatching in the thread, the var b will be assigned in the main thread.
I already have some workarounds but I just wondered if I'm doing something stupid or this is caused by other circumstances
I'm working with C# 8.0 and .Net Framework 4.7.2.
I'm running a Task in a new thread and want to wait for it to finish.
You want to use Task.Run
instead of StartNew
for that. StartNew
is a dangerous, low-level API that should almost never be used, and in the few cases where you should use it, you should always pass a TaskScheduler
.
await Application.Current.Dispatcher.BeginInvoke(new Action(async () =>
Imma stop you right there. First, you're explicitly creating an Action
delegate with async
, which results in an async void
method, which should be avoided. Next, using Dispatcher
to do any kind of Invoke
or BeginInvoke
really shouldn't be done at all.
Instead, use the Progress<T>
type. This keeps your logic in your background thread, which can pass objects as updates to the UI thread, and the UI thread decides how to display those progress updates in the UI. Note the nice separation of concerns there, which tends to go out the window whenever people start using Dispatcher
.
Both StartNew
and Dispatcher
are commonly seen in SO answers and blogs, but they're suboptimal solutions regardless.