9

给定以下方法:

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

有没有区别:

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

和:

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

我在想 DoSomethingAsync 的“做一些工作”部分会在第一种情况下立即发生在新任务中,但老实说,我并不完全了解 Tasks、async 和 await 是如何工作的,而且我很漂亮当然,我只是为自己把事情复杂化了。

编辑:

这个问题来自于查看这个 Metro 示例: http ://code.msdn.microsoft.com/windowsapps/Sharing-Content-Target-App-e2689782

特别是在 MainPage.xaml.cs 中,他们有这个:

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

我试图在不使用匿名异步函数的情况下对其进行返工,我开始想,为什么不写一个异步方法并等待它,而不是调用 StartNew 并提交一个异步函数呢?

4

2 回答 2

11

大多数情况下,添加另一个Task没有用,但在某些情况下,它可以。

不同之处在于,如果您在 UI 线程(或类似的线程)上并DoSomethingAsync()直接执行,它的第一部分 ( // do some work) 也将在 UI 线程上执行,该方法的任何延续部分也将执行(除非它们使用ConfigureAwait())。另一方面,如果您启动另一个Task,则第一部分和任何后续部分都DoSomethingAsync()将在ThreadPool.

如果DoSomethingAsync()编写正确,添加另一个Task不应该给您带来任何好处(并且会给您带来更多开销的缺点),但我可以想象在某些情况下它会有所作为。

此外,您可以编写而不是使用Task.Factory.StartNew()and 两个awaits:

await Task.Run(DoSomethingAsync);
于 2012-07-18T00:05:21.573 回答
4

是的,有一个区别:在第一种形式中,你有一个额外的任务级别,它绝对不会带来任何有用的东西。

第一种形式基本上等价于:

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

所以它真的没有意义:你正在创建一个任务,只是......创建另一个任务。

于 2012-07-17T22:58:52.020 回答