So, when looking at your code example. You have an async
method that return a Task
. You're calling that method, and then calling Start
on the resulting task (without calling await
). That will throw an exception at runtime. The task is already started just by calling the method. Starting an already running task (or a completed task, if it completed before it returned) will throw an exception. You can only Start
a task created using the Task
constructor, which you're not using.
You also claim, in comments, that you are not in the UI thread when you return after calling DoSomethingElse
. That is false. The code will run in the UI thread.
You also imply that the await
in DoSomethingElse
won't marshal the callback to the UI thread, but it will. Since it was called from the UI thread, it captured the UI context, and uses it when calling await
.
So in short, you need to do nothing except remove the call to Start
.
The one problem you do have, if you structure your code like this, is that you will never know if your code errors out, as there is nothing to observe any exceptions. There are two ways you could address this. One would be for each of the methods you call in this manor to consider themselves "top level methods" and handle all exceptions instead of every throwing any.
The other option would be to store all of the tasks called in this manner and await Task.WhenAll
those tasks, so you can observe any errors when they all finish.