簡體   English   中英

異步方法互相等待

[英]Async methods wait for each other

我正在嘗試運行異步程序。
主要有:

using System;
using System.Threading.Tasks;

namespace Test
{
class Program
{
    static void Main(string[] args)
    {
        RunTestsAsync().Wait();
    }

    private async static Task RunTestsAsync()
    {
        var a = new SlowString("ab", true);
        var b = new SlowString("c", true);

        var result1 = a.Equal(b);
        var result2 = b.Last(b);
        var result3 = b.GreaterThen(a);

        result1.Wait();
        result2.Wait();
        result3.Wait();

        Console.WriteLine();
        Console.WriteLine("Results: {0},   {1},   {2}", result1.Result, result2.Result, result3.Result);
        Console.WriteLine();
    }
}
}

這是第二個文件:

using System;
using System.Threading.Tasks;

namespace Test
{
class SlowString
{
    private readonly string str;
    private readonly bool msg;
    private readonly int delay;

    public SlowString(string str, bool msg = false, int delay = 30)
    {
        this.str = str;
        this.msg = msg;
        this.delay = delay;
    }

    public async Task<bool> Equal(SlowString other)
    {
        if(msg) Console.WriteLine("SlowString Equals Started");

        Task.Delay(delay).Wait();
        bool result = await Task.Run(() => { return str.Equals(other.str); });

        if (msg) Console.WriteLine("SlowString Equals Ended");

        return result;
    }

    public async Task<bool> GreaterThen(SlowString other)
    {
        if (msg) Console.WriteLine("SlowString GreaterThen Started");

        Task.Delay(delay).Wait();
        bool result = await Task.Run(() => { return str.CompareTo(other.str) > 0 ? true : false; });

        if (msg) Console.WriteLine("SlowString GreaterThen Ended");

        return result;
    }

    public async Task<SlowString> Last(SlowString other)
    {
        if (msg) Console.WriteLine("SlowString Last Started");

        Task.Delay(delay).Wait();
        SlowString result = await Task.Run(() => { return str.CompareTo(other.str) > 0 ? this : other; });

        if (msg) Console.WriteLine("SlowString Last Ended");

        return result;
    }

    public override string ToString()
    {
        return str;
    }
}
}

問題是我的程序總是等待以前的計算完成,所以我得到:

SlowString等於開始
SlowString等於結束
SlowString上次啟動
SlowString最后結束
SlowString GreaterThen開始
SlowString GreaterThen結束

即使延遲更大,例如3000ms的程序stil一直等到計算result1,
然后轉到result2並對其進行計算,然后再進行下一步。

我想我真的已經嘗試了一切。 請給我一些線索。

您正在調用.Wait() ,顧名思義,它等待任務完成。 阻止執行。 因此,第一件事永遠不會調用.Wait().Result或類似的東西。 始終awaitasync方法一起使用。

但是只是簡單地將.Wait()更改為await並不會這樣做,因為您試圖並行運行任務。 在這種情況下,您的例程應看起來像:

var result1 = Task.Run(() => a.Equal(b));
var result2 = Task.Run(() => b.Last(b));
var result3 = Task.Run(() => b.GreaterThen(a));

await Task.WhenAll(new [] {result1, result2, result3});

在其他說明上:

Task.Delay(delay).Wait();

也應該是

await Task.Delay(delay);

像這樣的行:

bool result = await Task.Run(() => { return str.CompareTo(other.str) > 0 ? true : false; });

除了施加開銷外,不要執行任何其他操作:您正在線程池上調用新任務,並立即等待結果。 它被同步包裹在人為的異步中。 這個:

bool result = str.CompareTo(other.str) > 0 ? true : false;

由於沒有開銷,因此可能會運行得更快。

您的Main方法應為:

static async Task Main(string[] args)
{
    await RunTestsAsync();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM