await AsyncMethod() versus await await Task.Factory.StartNew<TResult>(AsyncMethod)

11,166

Solution 1

Most of the time, adding another Task is not useful, but in some cases, it can be.

The difference is if you're on the UI thread (or something similar) and execute DoSomethingAsync() directly, its first part (// do some work) will also execute on the UI thread, and so will any continuation parts of the method (unless they use ConfigureAwait()). On the other hand, if you start another Task, both the first part and any following parts of DoSomethingAsync() will execute on the ThreadPool.

If DoSomethingAsync() is written correctly, adding another Task shouldn't give you any advantages (and will give you the disadvantage of more overhead), but I can imagine there are cases where it will make a difference.

Also, instead of using Task.Factory.StartNew() and two awaits, you could write:

await Task.Run(DoSomethingAsync);

Solution 2

Yes, there is a difference: in the first form, you have an extra level of Task, which brings absolutely nothing useful.

The first form is basically equivalent to this:

Task<Task<MyObject>> task1 = Task.Factory.StartNew<Task<MyObject>>( DoSomethingAsync);
Task<MyObject>> task2 = await task1;
var myObject = await task2;

So it doesn't really make sense: you're creating a task that just... creates another task.

Share:
11,166

Related videos on Youtube

Justin Lang
Author by

Justin Lang

Updated on September 15, 2022

Comments

  • Justin Lang
    Justin Lang over 1 year

    Given the following method:

    public async Task<MyObject> DoSomethingAsync() {
        // do some work
        await OpenSomeFileAsync();
        return new MyObject();
    }
    

    Is there a difference between:

    public async void SomeEventHandler(EventArgs args) {
        var myObject = await await Task.Factory.StartNew<Task<MyObject>>( DoSomethingAsync);
        // do something with myObject
    }
    

    and:

    public async void SomeEventHandler(EventArgs args) {
        var myObject = await DoSomethingAsync();
        // do something with myObject
    }
    

    I was thinking that the "do some work" part of DoSomethingAsync would happen immediately in a new task in the first case, but to be honest I don't really understand fully how Tasks, async and await are working, and I'm pretty sure I'm just overcomplicating things for myself.

    EDIT:

    This question came about from looking at this Metro example: http://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782

    Specifically in MainPage.xaml.cs, they have this:

    var unused = Task.Factory.StartNew(async () => { // some work... });
    // unused is of type Task<TResult>
    

    I was trying to rework it without using an anonymous async function and I started wondering, why not just write an async method and await it, instead of calling StartNew and handing in an async function?

  • Justin Lang
    Justin Lang almost 12 years
    Thanks for the response - I was thinking as much. If you have a moment could you address my edit? I'm sort of confused by the approach taken in the example I was looking at...
  • Thomas Levesque
    Thomas Levesque almost 12 years
    @justin, I agree with James, it's a really bad example... there's no reason to create a task on an async method, since it already returns a task
  • svick
    svick almost 12 years
    There is a difference between the two (and I don't mean just overhead), see my answer.
  • Thomas Levesque
    Thomas Levesque almost 12 years
    Good point, I didn't think about the part before the await... +1