-1

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?

JSteward
  • 6,396
  • 2
  • 17
  • 28
Sean B
  • 10,499
  • 2
  • 26
  • 38
  • 1
    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 '18 at 21:50
  • Task task = service.StartAsync(ct); blocks until the service completes, which is not the desired behavior. – Sean B Aug 31 '18 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 '18 at 13:21

1 Answers1

0

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.

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.

JSteward
  • 6,396
  • 2
  • 17
  • 28