[英]C# async await weird behavior
我是C#的新手,现在我正在尝试了解异步/等待功能。 所以我创建了一个小型沙箱应用程序:
namespace sandbox
{
public class Test
{
public async Task<string> GetItemsAsync()
{
var a = await Task1();
var b = await Task2();
var c = await Task3();
return a + b + c;
}
public string GetItems()
{
return _T1() + _T2() + _T3();
}
private readonly int cycles = 100000000;
private async Task<string> Task1()
{
return await Task.Factory.StartNew(_T1);
}
private async Task<string> Task2()
{
return await Task.Factory.StartNew(_T2);
}
private async Task<string> Task3()
{
return await Task.Factory.StartNew(_T3);
}
// long running operation
private string _T1()
{
for (int i = 0; i < cycles; i++) ;
for (int i = 0; i < cycles; i++) ;
return "One";
}
// long running operation
private string _T2()
{
for (int i = 0; i < cycles; i++) ;
for (int i = 0; i < cycles; i++) ;
return "Two";
}
// long running operation
private string _T3()
{
for (int i = 0; i < cycles; i++) ;
for (int i = 0; i < cycles; i++) ;
return "Three";
}
}
class Program
{
static void Main(string[] args)
{
var t = new Test();
Console.WriteLine("Async");
Stopwatch sw = new Stopwatch();
sw.Start();
var result = t.GetItemsAsync();
Console.WriteLine(result.Result);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
Console.WriteLine("Sync");
sw.Restart();
var strResult = t.GetItems();
Console.WriteLine(strResult);
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
Console.ReadLine();
}
}
}
但是结果很奇怪:
Async
OneTwoThree
1754
Sync
OneTwoThree
1506
异步方法比类似的方法运行时间更长。 对我来说,异步方法似乎是同步运行的,但我不知道为什么。
因为这:
var a = await Task1();
var b = await Task2();
var c = await Task3();
在甚至启动Task2
之前,您都已经等待Task1
完成。 因此,您不是并行运行它们,而是按顺序运行它们。
如果要启动所有3个任务,请等待它们完成,然后将此方法更改为:
public async Task<string> GetItemsAsync()
{
var t1 = Task1();
var t2 = Task2();
var t3 = Task3();
var a = await t1;
var b = await t2;
var c = await t3;
return a + b + c;
}
或者只是最后一部分:
return (await t1) + (await t2) + (await t3);
此外,此代码是反模式:
private async Task<string> Task3()
{
return await Task.Factory.StartNew(_T3);
}
您无需async/await
此处进行async/await
,因为在子任务返回之后,您无需再使用此方法做任何工作 。
相反,只需将此方法(及其同级)重写为:
private Task<string> Task3()
{
return Task.Factory.StartNew(_T3);
}
我怀疑这样做的目的是使所有三个任务并行完成。 那是可以实现它的选择之一:
public async Task<string> GetItemsAsync()
{
var a = Task1();
var b = Task2();
var c = Task3();
return string.Concat(await Task.WhenAll(a, b, c));
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.