繁体   English   中英

C#异步等待奇怪的行为

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM