簡體   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