我可能错过了一些东西,但做的和做的有什么区别:
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);
}
Wait(),将导致以同步方式运行潜在的异步代码。等待不会。
For example, you have an asp.net web application. UserA calls /getUser/1 endpoint. asp.net app pool will pick a thread from thread pool (Thread1) and, this thread will make a http call. If you do Wait(), this thread will be blocked until http call resolves. While it is waiting, if UserB calls /getUser/2, then, app pool will need to serve another thread (Thread2) to make http call again. You just created (Well, fetched from app pool actually) another thread for no reason, because you cannot use Thread1 it was blocked by Wait().
如果你在Thread1上使用await,那么SyncContext将管理Thread1和http调用之间的同步。简单地说,它将在http调用完成后通知。同时,如果UserB调用/getUser/2,那么,你将再次使用Thread1进行http调用,因为它在await被命中时被释放。然后另一个请求可以使用它,甚至更多。一旦http调用完成(user1或user2), Thread1就可以获得结果并返回给调用方(客户端)。Thread1用于多个任务。
Wait(),将导致以同步方式运行潜在的异步代码。等待不会。
For example, you have an asp.net web application. UserA calls /getUser/1 endpoint. asp.net app pool will pick a thread from thread pool (Thread1) and, this thread will make a http call. If you do Wait(), this thread will be blocked until http call resolves. While it is waiting, if UserB calls /getUser/2, then, app pool will need to serve another thread (Thread2) to make http call again. You just created (Well, fetched from app pool actually) another thread for no reason, because you cannot use Thread1 it was blocked by Wait().
如果你在Thread1上使用await,那么SyncContext将管理Thread1和http调用之间的同步。简单地说,它将在http调用完成后通知。同时,如果UserB调用/getUser/2,那么,你将再次使用Thread1进行http调用,因为它在await被命中时被释放。然后另一个请求可以使用它,甚至更多。一旦http调用完成(user1或user2), Thread1就可以获得结果并返回给调用方(客户端)。Thread1用于多个任务。
这个例子非常清楚地说明了其中的区别。使用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来改进示例。