掌握C#中非同步魔法:同步方法如何優雅呼叫非同步方法

架构师老卢發表於2024-03-25
掌握C#中非同步魔法:同步方法如何優雅呼叫非同步方法

概述:上述C#示例演示瞭如何在同步方法中呼叫非同步方法。透過使用`async`和`await`關鍵字,實現了同步方法對非同步方法的呼叫。建議使用`await`而不是`Result`來避免潛在的死鎖問題。這種模式在處理非同步任務時能夠提高程式碼的可讀性和效能。

在C#中,從同步方法呼叫非同步方法的過程涉及到使用非同步程式設計的關鍵字和模式,主要涉及asyncawait關鍵字。以下是一個簡單的例子,展示如何在同步方法中呼叫非同步方法:

using System;
using System.Threading.Tasks;

class Program
{
    static void Main()
    {
        // 同步方法呼叫非同步方法
        CallAsyncMethodSynchronously();

        Console.ReadLine();
    }

    // 非同步方法
    static async Task<int> AsyncMethod()
    {
        Console.WriteLine("非同步方法開始執行...");
        
        // 模擬非同步操作,比如從資料庫或遠端服務獲取資料
        await Task.Delay(2000);

        Console.WriteLine("非同步方法執行完成。");

        return 42;
    }

    // 同步方法呼叫非同步方法
    static void CallAsyncMethodSynchronously()
    {
        Console.WriteLine("同步方法開始執行...");

        // 同步方法中呼叫非同步方法,使用Wait()方法等待非同步方法完成
        Task<int> asyncTask = AsyncMethod();
        int result = asyncTask.Result; // 使用Result屬性會阻塞當前執行緒,直到非同步方法完成

        Console.WriteLine($"非同步方法返回的結果為: {result}");
        
        Console.WriteLine("同步方法執行完成。");
    }
}

在上面的例子中,AsyncMethod是一個非同步方法,它模擬了一個非同步操作。然後,
CallAsyncMethodSynchronously
是一個同步方法,它呼叫了非同步方法,並使用asyncTask.Result等待非同步方法完成。請注意,使用Result屬性可能會導致阻塞當前執行緒,這在UI執行緒中可能會引起死鎖問題,因此在實際應用中應該避免在UI執行緒上使用Result

另外,更推薦的方式是在非同步方法中使用await關鍵字,而不是在同步方法中使用Result。以下是使用await的改進版本:

using System;
using System.Threading.Tasks;

class Program
{
    static async Task Main()
    {
        // 非同步方法呼叫
        await CallAsyncMethod();

        Console.ReadLine();
    }

    // 非同步方法
    static async Task<int> AsyncMethod()
    {
        Console.WriteLine("非同步方法開始執行...");
        
        // 模擬非同步操作,比如從資料庫或遠端服務獲取資料
        await Task.Delay(2000);

        Console.WriteLine("非同步方法執行完成。");

        return 42;
    }

    // 同步方法呼叫非同步方法
    static async Task CallAsyncMethod()
    {
        Console.WriteLine("同步方法開始執行...");

        // 使用await等待非同步方法完成
        int result = await AsyncMethod();

        Console.WriteLine($"非同步方法返回的結果為: {result}");
        
        Console.WriteLine("同步方法執行完成。");
    }
}

在這個改進版本中,CallAsyncMethod方法標記為async,並使用await關鍵字等待非同步方法完成,而不是阻塞執行緒使用Result。這樣能夠更好地保持非同步的特性,避免潛在的死鎖問題。

原始碼獲取:https://pan.baidu.com/s/1THRY6OV6aQYTcN2F2yX4QQ?pwd=6666

相關文章