首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

C# IProgress.Report 異步進度報告如何等待完成?Task.Run 替代方案詳解

     編輯:程式設計綜合問答

問題背景

IProgress.Report 返回 void,無法 await,需在進度報告完成後執行後續邏輯。

核心誤區

Progress.Report 只是同步調用傳遞給 Progress 構造函數的 Action,本身不涉及異步。若報告動作耗時,應將耗時邏輯放入 Task.Run,而非指望 Report 異步化。

推薦模式:Task.Run 封裝耗時操作

// 1. 定義耗時操作返回結果
Func updateAction = () => UpdateResult(dictionaryStockReal[stockCode]);

// 2. 線程池異步執行
var task = Task.Run(updateAction);

// 3. 可選:同步進度報告(UI 線程)
progress.Report("開始更新...");

// 4. 等待完成並獲取結果
int result = await task; // 異步等待,不阻塞 UI

// 5. 後續邏輯
if (result == 1) { ... }

為什麼不用 IProgress.Report 等待?

  • IProgress 設計目的是跨線程安全回調 UI,而非任務協調。
  • 其內部實現只是 SynchronizationContext.Post,無異步等待語義。
  • 任務協調請用 Task/ValueTask/TaskCompletionSource。

進階:組合進度報告與任務等待

public async Task DoWorkWithProgress(IProgress progress) {
    progress.Report("階段1: 解析數據");
    var data = await Task.Run(() => ParseData());

    progress.Report("階段2: 計算結果");
    int result = await Task.Run(() => Compute(data));

    progress.Report("完成");
    return result;
}

// 調用
var progress = new Progress(msg => txtLog.AppendText(msg + "\n"));
int result = await DoWorkWithProgress(progress);

總結

拋棄 IProgress.Report 的等待幻想,用 Task.Run 承載耗時邏輯,await 等待完成,Progress.Report 僅用於同步推送進度文本到 UI。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved