了解 .Net 中的异步和等待
Understanding Async and await in .Net
从下面的示例中,我无法理解为什么 async
和 await
在第一个示例中不起作用,但在第二个示例中起作用。
第一个示例:
public static async Task Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Console.WriteLine("started");
var i = await GetIntAsync(10);
var j = await GetstringAsync("abc");
Console.WriteLine($"int {i}, string {j}");
stopWatch.Stop();
Console.WriteLine("RunTime " + stopWatch.ElapsedMilliseconds);
}
第二个例子:
public static async Task Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Console.WriteLine("started");
var i = GetIntAsync(10);
var j = GetstringAsync("abc");
await i; await j;
Console.WriteLine($"int {i.Result}, string {j.Result}");
stopWatch.Stop();
Console.WriteLine("RunTime " + stopWatch.ElapsedMilliseconds);
}
GetIntAsync
方法:
public static async Task<int> GetIntAsync(int i)
{
Console.WriteLine("in get int waiting 3 sec's");
await Task.Run(() =>
{
Thread.Sleep(3000);
Console.WriteLine("int wait complete");
});
return i;
}
GetstringAsync
方法:
public static async Task<string> GetstringAsync(string i)
{
Console.WriteLine("in get int waiting 6 sec's");
await Task.Run(() =>
{
Thread.Sleep(6000);
Console.WriteLine("string wait complete");
});
return i;
}
看来您误解了 async
和 await
的作用。常见的误解。
Async Await 不是并发。
我怀疑您希望 GetIntAsync 和 GetstringAsync 应该 运行 并行。
在 Rx Marble 图中含义:
---o
-------o
您在哪里找到的:
---o
------o
让我们分解一下您实际写的内容。
var i = await GetIntAsync(10);
var j = await GetstringAsync("abc");
可展开为:
var taskI = GetIntAsync(10);
var i = await taskI;
var taskJ = GetstringAsync("abc");
var j = await taskJ;
注意你启动 taskI,等待它完成,然后你启动 taskJ,然后等待它完成。
如示例 2(重新格式化后):
var taskI = GetIntAsync(10);
var taskJ = GetstringAsync("abc");
var i = await taskI;
var j = await taskJ;
注意顺序发生了怎样的变化。
仅供参考:您也可以这样做
public static class TaskEx
{
public static async Task<(T1, T2)> WhenAll<T1, T2>(Task<T1> task1, Task<T2> task2)
{
return (await task1, await task2);
}
}
var (i, j) = await TaskEx.WhenAll(
GetIntAsync(10),
GetstringAsync("abc"));
从下面的示例中,我无法理解为什么 async
和 await
在第一个示例中不起作用,但在第二个示例中起作用。
第一个示例:
public static async Task Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Console.WriteLine("started");
var i = await GetIntAsync(10);
var j = await GetstringAsync("abc");
Console.WriteLine($"int {i}, string {j}");
stopWatch.Stop();
Console.WriteLine("RunTime " + stopWatch.ElapsedMilliseconds);
}
第二个例子:
public static async Task Main(string[] args)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
Console.WriteLine("started");
var i = GetIntAsync(10);
var j = GetstringAsync("abc");
await i; await j;
Console.WriteLine($"int {i.Result}, string {j.Result}");
stopWatch.Stop();
Console.WriteLine("RunTime " + stopWatch.ElapsedMilliseconds);
}
GetIntAsync
方法:
public static async Task<int> GetIntAsync(int i)
{
Console.WriteLine("in get int waiting 3 sec's");
await Task.Run(() =>
{
Thread.Sleep(3000);
Console.WriteLine("int wait complete");
});
return i;
}
GetstringAsync
方法:
public static async Task<string> GetstringAsync(string i)
{
Console.WriteLine("in get int waiting 6 sec's");
await Task.Run(() =>
{
Thread.Sleep(6000);
Console.WriteLine("string wait complete");
});
return i;
}
看来您误解了 async
和 await
的作用。常见的误解。
Async Await 不是并发。
我怀疑您希望 GetIntAsync 和 GetstringAsync 应该 运行 并行。
在 Rx Marble 图中含义:
---o
-------o
您在哪里找到的:
---o
------o
让我们分解一下您实际写的内容。
var i = await GetIntAsync(10);
var j = await GetstringAsync("abc");
可展开为:
var taskI = GetIntAsync(10);
var i = await taskI;
var taskJ = GetstringAsync("abc");
var j = await taskJ;
注意你启动 taskI,等待它完成,然后你启动 taskJ,然后等待它完成。
如示例 2(重新格式化后):
var taskI = GetIntAsync(10);
var taskJ = GetstringAsync("abc");
var i = await taskI;
var j = await taskJ;
注意顺序发生了怎样的变化。
仅供参考:您也可以这样做
public static class TaskEx
{
public static async Task<(T1, T2)> WhenAll<T1, T2>(Task<T1> task1, Task<T2> task2)
{
return (await task1, await task2);
}
}
var (i, j) = await TaskEx.WhenAll(
GetIntAsync(10),
GetstringAsync("abc"));