我可能错过了一些东西,但做的和做的有什么区别:

public void MyMethod()
{
  Task t = Task.Factory.StartNew(DoSomethingThatTakesTime);
  t.Wait();
  UpdateLabelToSayItsComplete();
}

public async void MyMethod()
{
  var result = Task.Factory.StartNew(DoSomethingThatTakesTime);
  await result;
  UpdateLabelToSayItsComplete();
}

private void DoSomethingThatTakesTime()
{
  Thread.Sleep(10000);
}

当前回答

我可能遗漏了什么

你。

做任务之间有什么区别。等待任务?

你从餐厅的服务员那里点了午餐。你点完餐后不久,一位朋友走进来,坐在你旁边,开始和你聊天。现在你有两个选择。你可以无视你的朋友,直到任务完成——你可以等到你的汤上来,在等待的时候什么也不做。或者你可以回应你的朋友,当你的朋友停止说话时,服务员会给你端来汤。

的任务。等待块,直到任务完成——你忽略你的朋友,直到任务完成。Await继续处理消息队列中的消息,当任务完成时,它将一条消息编入队列,该消息表示“在等待之后从您离开的地方重新开始”。你和你的朋友聊天,当谈话中断时,汤端上来了。

其他回答

这个例子非常清楚地说明了其中的区别。使用async/await,调用线程将不会阻塞并继续执行。

static void Main(string[] args)
{
    WriteOutput("Program Begin");
    // DoAsTask();
    DoAsAsync();
    WriteOutput("Program End");
    Console.ReadLine();
}

static void DoAsTask()
{
    WriteOutput("1 - Starting");
    var t = Task.Factory.StartNew<int>(DoSomethingThatTakesTime);
    WriteOutput("2 - Task started");
    t.Wait();
    WriteOutput("3 - Task completed with result: " + t.Result);
}

static async Task DoAsAsync()
{
    WriteOutput("1 - Starting");
    var t = Task.Factory.StartNew<int>(DoSomethingThatTakesTime);
    WriteOutput("2 - Task started");
    var result = await t;
    WriteOutput("3 - Task completed with result: " + result);
}

static int DoSomethingThatTakesTime()
{
    WriteOutput("A - Started something");
    Thread.Sleep(1000);
    WriteOutput("B - Completed something");
    return 123;
}

static void WriteOutput(string message)
{
    Console.WriteLine("[{0}] {1}", Thread.CurrentThread.ManagedThreadId, message);
}

DoAsTask输出:

[1] Program Begin
[1] 1 - Starting
[1] 2 - Task started
[3] A - Started something
[3] B - Completed something
[1] 3 - Task completed with result: 123
[1] Program End

DoAsAsync输出:

[1] Program Begin
[1] 1 - Starting
[1] 2 - Task started
[3] A - Started something
[1] Program End
[3] B - Completed something
[3] 3 - Task completed with result: 123

更新:通过在输出中显示线程ID来改进示例。

在上面的例子中,你可以使用“TaskCreationOptions”。HideScheduler”,并极大地修改了“DoAsTask”方法。该方法本身不是异步的,因为它发生在“DoAsAsync”,因为它返回一个“Task”值,并标记为“async”,进行了几个组合,这就是它如何给我完全相同的使用“async / await”:

static Task DoAsTask()
{
    WriteOutput("1 - Starting");
    var t = Task.Factory.StartNew<int>(DoSomethingThatTakesTime, TaskCreationOptions.HideScheduler); //<-- HideScheduler do the magic

    TaskCompletionSource<int> tsc = new TaskCompletionSource<int>();
    t.ContinueWith(tsk => tsc.TrySetResult(tsk.Result)); //<-- Set the result to the created Task

    WriteOutput("2 - Task started");

    tsc.Task.ContinueWith(tsk => WriteOutput("3 - Task completed with result: " + tsk.Result)); //<-- Complete the Task
    return tsc.Task;
}

为了演示Eric的回答,这里有一些代码:

public void ButtonClick(object sender, EventArgs e)
{
  Task t = new Task.Factory.StartNew(DoSomethingThatTakesTime);
  t.Wait();  
  //If you press Button2 now you won't see anything in the console 
  //until this task is complete and then the label will be updated!
  UpdateLabelToSayItsComplete();
}

public async void ButtonClick(object sender, EventArgs e)
{
  var result = Task.Factory.StartNew(DoSomethingThatTakesTime);
  await result;
  //If you press Button2 now you will see stuff in the console and 
  //when the long method returns it will update the label!
  UpdateLabelToSayItsComplete();
}

public void Button_2_Click(object sender, EventArgs e)
{
  Console.WriteLine("Button 2 Clicked");
}

private void DoSomethingThatTakesTime()
{
  Thread.Sleep(10000);
}

在这个例子中,实际上没有太多。如果你正在等待一个Task在不同的线程上返回(比如WCF调用),或者放弃对操作系统的控制(比如File IO), await不会阻塞线程,从而使用更少的系统资源。

我可能遗漏了什么

你。

做任务之间有什么区别。等待任务?

你从餐厅的服务员那里点了午餐。你点完餐后不久,一位朋友走进来,坐在你旁边,开始和你聊天。现在你有两个选择。你可以无视你的朋友,直到任务完成——你可以等到你的汤上来,在等待的时候什么也不做。或者你可以回应你的朋友,当你的朋友停止说话时,服务员会给你端来汤。

的任务。等待块,直到任务完成——你忽略你的朋友,直到任务完成。Await继续处理消息队列中的消息,当任务完成时,它将一条消息编入队列,该消息表示“在等待之后从您离开的地方重新开始”。你和你的朋友聊天,当谈话中断时,汤端上来了。