Is async and unwrap necessary for StartNew()? [duplicate]
Is async and unwrap necessary for StartNew()? [duplicate]
This question already has an answer here:
I have this code:
var task = Task.Factory.StartNew(() => service.StartAsync(ct), ct);
but I'm wondering if it should instead be this:
var task = Task.Factory.StartNew(async () => await service.StartAsync(ct), ct).Unwrap();
Is the first one correct to start my async service? Or is the second one better?
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
var task = service.StartAsync(ct);
Task task = service.StartAsync(ct); blocks until the service completes, which is not the desired behavior.
– Sean B
Aug 31 at 13:00
No, it doesn't. It's asynchronous. That's why it has
Async in the name and returns a Task. If it's not asynchronous, it shouldn't return a Task and it shouldn't have Async in the name, or it has a bug that you need to fix to make it asynchronous.– Servy
Aug 31 at 13:21
Async
Task
Task
Async
1 Answer
1
Consider the type of task returned, the first one yields Task<Task<int>> while the second yields Task<int>. So really the first one is a Task representing starting of the inner task, while the second, unwrapped, represents the Task returned by the inner method representing the service starting. Finally you can also Unwrap the first and get the same effect without the async/await which is unnecessary here. None of this really covers what the need for StartNew is at all in this case just reviews the return types your looking at.
Task<Task<int>>
Task<int>
Task
Task
Unwrap
async/await
StartNew
Consider the following code:
public class AsyncTesting
public void StartServiceTest()
Task<Task<int>> tsk1 = Task.Factory.StartNew(() => StartAsync());
Task<int> tsk2 = Task.Factory.StartNew(() => StartAsync()).Unwrap();
Task<int> tsk3 = Task.Factory.StartNew(async () => await StartAsync()).Unwrap();
public Task<int> StartAsync() => Task.Delay(2500).ContinueWith(tsk => 1);
The method that does not Unwrap returns a Task that represents starting the internal Task not the work it does.
Unwrap
Task
Task
Rather than creating a task, wrapping it in another task, unwrapping it in another task, wrapping it in a task again, and unwrapping it in a task again, why not just not wrap the task in another task in the first place? Just write
var task = service.StartAsync(ct);, given that the operation is already asynchronous.– Servy
Aug 30 at 21:50