我是C#的新手,现在我正在尝试了解async / await feautures。所以我创建了小沙盒应用程序:
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
异步方法的运行时间比类似的同步方法长。对我来说,看起来异步方法同步运行,但我无法弄清楚原因。
答案 0 :(得分:4)
因此:
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
,因为您在子任务返回后,您在此方法中没有再做任何工作了。
而是简单地将此方法(及其兄弟姐妹)重写为:
private Task<string> Task3()
{
return Task.Factory.StartNew(_T3);
}
答案 1 :(得分:1)
我怀疑其目的是让所有三个任务并行完成。这是如何实现的选择之一:
public async Task<string> GetItemsAsync()
{
var a = Task1();
var b = Task2();
var c = Task3();
return string.Concat(await Task.WhenAll(a, b, c));
}