天天看點

C# Task 常用方法淺析(二)

作者:步伐科技

三、Task.Factory.StartNew() 方法

Task.Factory.StartNew 方法與 Task.Run 類似,也是用于在新線程或線程池線程上運作指定的操作。但是,Task.Factory.StartNew 更加靈活,可以自定義 Task 對象的屬性和行為,例如指定 Task 的排程器、建立帶傳回值的 Task 等。

以下是一些常見的使用 Task.Factory.StartNew 的場景:

  1. 自定義排程器:當需要使用自定義的排程器(例如 TaskScheduler.FromCurrentSyncContext)來控制 Task 的執行時,可以使用 Task.Factory.StartNew 方法。
  2. 定義 Task 的屬性:當需要設定額外的 Task 屬性,例如 TaskCreationOptions、TaskContinuationOptions 等時,可以使用 Task.Factory.StartNew 方法。
  3. 建立帶傳回值的 Task:當需要傳回值的 Task 時,可以使用 Task.Factory.StartNew 方法并指定傳回值類型。

需要注意的是,Task.Factory.StartNew 方法的參數比 Task.Run 多很多,需要根據具體情況來選擇使用。同時,在使用 Task.Factory.StartNew 建立 Task 時,也需要根據實際情況進行異常處理、線程安全控制等,保證程式的穩定性和可靠性。

下面給出一些使用 Task.Factory.StartNew 的執行個體:

  1. 自定義排程器
Task.Factory.StartNew(() =>
{
    // 在目前同步上下文(即 UI 線程)中執行某個操作
    Console.WriteLine("Task.Factory.StartNew is running on thread {0}", Thread.CurrentThread.ManagedThreadId);
}, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());           
  1. 定義 Task 的屬性
Task.Factory.StartNew(() =>
{
    // 在新線程上執行某個操作
    Console.WriteLine("Task.Factory.StartNew is running on thread {0}", Thread.CurrentThread.ManagedThreadId);
}, CancellationToken.None, TaskCreationOptions.LongRunning, TaskScheduler.Default);           
  1. 建立帶傳回值的 Task
Task<int> task = Task.Factory.StartNew(() =>
{
    // 在新線程上執行某個操作,并傳回一個整數值
    Console.WriteLine("Task.Factory.StartNew is running on thread {0}", Thread.CurrentThread.ManagedThreadId);
    return 42;
});

Console.WriteLine("Result from task: {0}", await task);           

以上是一些使用 Task.Factory.StartNew 的執行個體,需要注意的是,在實際程式設計中應該根據具體場景選擇合适的使用方式,并結合異常處理和線程安全控制來保證程式的穩定性和可靠性。

四、Task.FromResult() 方法

Task.FromResult 方法通常用于建立一個已完成的 Task,它的傳回值即為指定的結果。它可以讓你将任意類型的值轉換為一個完成的 Task,同時允許在 Task 建立後立即通路其結果,而不需要等待 Task 對應的異步操作完成。

以下是一些常見的使用 Task.FromResult 的場景:

  1. 将同步代碼轉換為異步:當需要将同步方法轉換為異步方法時,可以使用 Task.FromResult 方法,将同步方法中的傳回值轉換為 Task 的結果。
  2. 緩存計算結果:當需要緩存某個計算結果時,可以使用 Task.FromResult 方法,建立一個已完成的 Task,并将計算結果作為 Task 的傳回值。這樣下一次請求時,可以直接通路緩存中的 Task 擷取結果,而不需要再次執行計算操作。

下面給出一些使用 Task.FromResult 的執行個體:

  1. 将同步代碼轉換為異步
async Task<int> MyAsyncMethod()
{
    // 執行某個同步操作,例如計算 42 的平方
    int result = 42 * 42;

    // 将計算結果轉換為已完成的 Task
    return await Task.FromResult(result);
}           
  1. 緩存計算結果
private static readonly ConcurrentDictionary<int, Task<string>> cache = new ConcurrentDictionary<int, Task<string>>();

async Task<string> MyAsyncMethod(int value)
{
    // 嘗試從緩存中擷取結果
    if (cache.TryGetValue(value, out Task<string> task))
    {
        return await task;
    }

    // 否則,執行計算操作,并将結果放入緩存中
    task = Task.FromResult(#34;The result of calculation is {value * value}.");
    cache.TryAdd(value, task);

    return await task;
}           

需要注意的是,Task.FromResult 方法建立的 Task 是一個已完成的 Task,是以無需等待其異步操作完成。同時,在使用 Task.FromResult 時,應該根據實際情況選擇合适的執行上下文,并結合異常處理等來保證程式的穩定性和可靠性。

創作不易,如果您喜歡還請點贊關注,謝謝!

繼續閱讀