C# await AsyncMethod()与await await Task.Factory.StartNew的比较<;TResult>;(异步方法)

C# await AsyncMethod()与await await Task.Factory.StartNew的比较<;TResult>;(异步方法),c#,asynchronous,task,async-await,C#,Asynchronous,Task,Async Await,根据以下方法: public async Task<MyObject> DoSomethingAsync() { // do some work await OpenSomeFileAsync(); return new MyObject(); } 我原以为在第一种情况下,DoSomethingAsync的“做一些工作”部分会在一个新任务中立即发生,但老实说,我并不完全理解任务async和await是如何工作的,我很确定我只是把事情过度复杂化了 编辑: 这个

根据以下方法:

public async Task<MyObject> DoSomethingAsync() {
    // do some work
    await OpenSomeFileAsync();
    return new MyObject();
}
我原以为在第一种情况下,DoSomethingAsync的“做一些工作”部分会在一个新任务中立即发生,但老实说,我并不完全理解任务async和await是如何工作的,我很确定我只是把事情过度复杂化了

编辑:

这个问题来自于看这个Metro示例:

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

var unused = Task.Factory.StartNew(async () => { // some work... });
// unused is of type Task<TResult>
var unused=Task.Factory.StartNew(async()=>{//some work…});
//未使用的是任务类型

我试图在不使用匿名异步函数的情况下重新编写它,我开始思考,为什么不编写一个异步方法并等待它,而不是调用StartNew并提交一个异步函数?

是的,有一个区别:在第一种形式中,您有一个额外的任务级别,这绝对没有带来任何有用的东西

第一种形式基本上等同于此:

Task<Task<MyObject>> task1 = Task.Factory.StartNew<Task<MyObject>>( DoSomethingAsync);
Task<MyObject>> task2 = await task1;
var myObject = await task2;
Task task1=Task.Factory.StartNew(DoSomethingAsync);
任务>任务2=等待任务1;
var myObject=wait task2;

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

大多数情况下,添加另一个
任务
是没有用的,但在某些情况下,它可能是有用的

不同之处在于,如果您在UI线程(或类似的线程)上,并且直接执行
DoSomethingAsync()
,那么它的第一部分(
//做一些工作
)也将在UI线程上执行,方法的任何后续部分也将在UI线程上执行(除非它们使用
ConfigureAwait()
)。另一方面,如果启动另一个
任务
,则
DoSomethingAsync()
的第一部分和任何后续部分都将在
线程池
上执行

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

另外,您可以编写以下代码,而不是使用
Task.Factory.StartNew()
和两个
wait
s:

await Task.Run(DoSomethingAsync);

你为什么要这样写?使用新的
async
/
await
关键字的全部目的是为了让您不必这么做。似乎是一个不好的示例代码。我只是自己看了一下,然后。。。哇!是的,“官方Windows SDK示例”代码真的很糟糕!我认为他们完全忽略了
async
的要点!谢谢你的回复,我也这么想。如果你有时间的话,你能谈谈我的编辑吗?我对我所看到的例子中所采用的方法有些困惑…@justin,我同意James的观点,这是一个非常糟糕的例子。。。没有理由在异步方法上创建一个任务,因为它已经返回了一个任务。这两者之间有区别(我不是指开销),请看我的答案。好的一点,我没有考虑等待之前的部分+1.
Task<Task<MyObject>> task1 = Task.Factory.StartNew<Task<MyObject>>( DoSomethingAsync);
Task<MyObject>> task2 = await task1;
var myObject = await task2;
await Task.Run(DoSomethingAsync);