簡體   English   中英

異步/等待單線程/一些線程

[英]Async/Await single thread/some threads

我需要一個關於正確使用await的規則。 在.net core c#7.2中運行此代碼:

static class Program
{
    static async Task<string> GetTaskAsync(int timeout)
    {
        Console.WriteLine("Task Thread: " + Thread.CurrentThread.ManagedThreadId);
        await Task.Delay(timeout);
        return timeout.ToString();
    }

    static async Task Main()
    {
        Console.WriteLine("Main Thread: " + Thread.CurrentThread.ManagedThreadId);

        Console.WriteLine("Should be greater than 5000");
        await Watch(NotParallel);
        Console.WriteLine("Should be less than 5000");
        await Watch(Parallel);
    }

    public static async Task Parallel()
    {
        var res1 = GetTaskAsync(2000);
        var res2 = GetTaskAsync(3000);

        Console.WriteLine("result: " + await res1 + await res2);
    }

    public static async Task NotParallel()
    {
        var res1 = await GetTaskAsync(2000);
        var res2 = await GetTaskAsync(3000);

        Console.WriteLine("result: " + res1 + res2);
    }

    private static async Task Watch(Func<Task> func) {
        var sw = new Stopwatch();
        sw.Start();

        await func?.Invoke();

        sw.Stop();
        Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds);
        Console.WriteLine("---------------");
    }
}

你們都可以看到兩種方法的行為是不同的。 在實踐中很容易出錯。 所以我需要一個“拇指規則”。

真人的更新請運行代碼。 並解釋為什么Parallel()比NonParallel()運行得更快。

結果,女士們。

在沒有await情況下調用GetTaskAsync ,你實際上得到一個Task,其中包含要執行的方法(即GetTaskAsync )。但是當調用await GetTaskAsync ,執行將暫停,直到方法執行await GetTaskAsync ,然后你得到結果。

讓我更清楚一點:

var task = GetTaskAsync(2000);

這里,task的類型為Task<string>

var result = await GetTaskAsync(2000);

這里的結果是string類型。

因此,要解決您的第一次詢問:何時等待您的任務實際上取決於您的執行流程。

現在,至於為什么Parallel()更快,我建議你閱讀這篇文章 (一切都很有趣,但對於你的具體例子,你可以跳轉到Tasks返回“熱門” )。

現在讓我們分解一下:

await關鍵字用於暫停代碼,直到任務完成,但實際上並未啟動它。

在您的示例中, NotParallel()將花費更長時間,因為您的任務依次執行,一個接一個地執行。 正如文章所解釋的:

這是由於正在等待內聯任務。

Parallel()然而......

這些任務現在並行運行。 這是因為所有[任務]在隨后等待所有[任務]之前開始,因為它們返回熱點。

關於'熱'任務

我建議您閱讀以下內容: 基於任務的異步模式(TAP)

此處的“ 任務狀態”部分非常感興趣,可以了解冷熱任務的概念:

由公共任務構造函數創建的任務稱為冷任務,因為它們以非調度的創建狀態開始其生命周期,並且僅在這些實例上調用Start時進行調度。

所有其他任務在熱狀態下開始其生命周期,這意味着它們所代表的異步操作已經啟動

我邀請您詳細閱讀有關async/awaitTasks 除了上面提供的資源之外,還有一些資源:

C#5.0中的異步編程第二部分:從哪里等待?

Async / Await - 異步編程的最佳實踐

異步和等待

暫無
暫無

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

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