1

I'm doing some connecting-to-a-service-magic during the initialization of a ViewModel.

This logic is placed and awaited inside a Task.Run() because I want the View to show prior to the completion of the returned task, thus I'm not awaiting it.

public override async Task Initialize()
{
    await base.Initialize();

    Task.Run(async () =>
    {
        await ConnectToServiceAsync();

        // Do other stuff that requires the service connection
    });
}

Now if anything goes wrong during that process and exceptions are thrown around, they will not be unwrapped (because the task is not awaited) and I can't catch them anywhere on that level (or at least I don't know how).

How can I handle exceptions that are thrown inside that Task.Run()?

...I have a feeling that the solution it's related to .ConfigureAwait(false).
Unfortunately, I couldn't quite wrap my head around it so far.

toogeneric
  • 53
  • 6
  • 2
    "...I have a feeling that the solution it's related to `.ConfigureAwait(false).`" no, it is not. – Guru Stron Apr 26 '21 at 19:51
  • 5
    Why not just await the task? – Guru Stron Apr 26 '21 at 19:52
  • 7
    Why use `Task.Run` at all? Do you really need to start a new thread for an I/O-bound operation and block this thread while waiting on the new one? – madreflection Apr 26 '21 at 19:52
  • Task.Run(() => throw new Exception("Oops")) .ContinueWith(task => Console.WriteLine(task.Exception.Message), TaskContinuationOptions.OnlyOnFaulted); – Klamsi Apr 26 '21 at 20:09
  • 1
    @madreflection the `Task.Run(async` doesn't start a new thread. It reuses a `ThreadPool` thread. A possible reason for using it is to ensure that the `ConnectToServiceAsync()` invocation will not block the current thread. This offers a protection against badly implemented asynchronous methods, that don't return an incomplete task immediately as they should. The overhead of using a `Task.Run(async` is minuscule. The `ThreadPool` is an efficient mechanism, you can trust it. – Theodor Zoulias Apr 26 '21 at 20:27
  • 1
    Use `await`. That's what it's for. You need a very good reason to avoid it. If you have such a good reason you should make it explicit in the question itself, because it will affect *every* other solution. If you can't use `await` for example, there's no guarantee `.ContinueWith` will have a chance to handle exceptions before the application or appdomain is terminated, or any objects get garbage collected – Panagiotis Kanavos Apr 26 '21 at 21:07
  • Sorry for the late reply guys. Stephen answered my question in the duplicate - pretty straight forward. I had actually tried that but had some major convolution in my try-catch game which is why the exception eventually never bubbled up to the upmost try-catch. – toogeneric Apr 27 '21 at 06:42

0 Answers0