首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> 關於.NET

Web Service 大量資料傳輸解決方案:多執行緒分段獲取實戰

     編輯:關於.NET

前言:單請求 10 萬筆訂單的效能困境

呼叫 Web Service 一次性取回 100,000 筆訂單,易導致:

  • 請求逾時 (Timeout)
  • 記憶體暴漲 (OOM)
  • 序列化/反序列化耗時過長
  • 網路傳輸封包過大、易中斷

本文提出 多執行緒分段拉取 策略:將 10 萬筆拆為 10 執行緒 × 1 萬筆,流水線式並行處理。

流程圖與核心邏輯

多執行緒分段獲取流程圖

步驟說明

  1. Thread 1 發起請求,取得第 1~10,000 筆。
  2. 資料回傳成功 → Service 端閒置 → Thread 2 立即發起第 10,001~20,000 筆請求,同時 Thread 1 進入後續處理 (反序列化、入庫)。
  3. 以此類推,形成「請求-處理」流水線,最大化頻寬與 CPU 利用率。
  4. 所有執行緒完成 → 合併結果或分別持久化。

關鍵技術選型

  • 分頁參數:Web Method 需支援 pageIndex/pageSize 或 startId/endId。
  • 反序列化:預定義實體類 → XmlSerializer.Deserialize 直映射物件,比 XmlDocument 遍歷或 DataSet 填充更高效 (未實測,經驗值)。
  • 執行緒控制:ThreadPool.QueueUserWorkItem 或 Parallel.ForEach (NET 4+) 配合 SemaphoreSlim 限制並發數。
  • 錯誤重試:單段失敗記錄日誌、指數退避重試,不影響其他段。

偽代碼實現 (C# 4.0 Parallel 版)


const int Total = 100_000;
const int PageSize = 10_000;
const int MaxDegree = 5; // 視頻寬/服務端承受力調整

var partitions = Enumerable.Range(0, (Total + PageSize - 1) / PageSize)
    .Select(i => new { Start = i * PageSize, Count = PageSize });

var options = new ParallelOptions { MaxDegreeOfParallelism = MaxDegree };

Parallel.ForEach(partitions, options, part =>
{
    try
    {
        var xml = WebServiceClient.GetOrders(part.Start, part.Count); // 呼叫 WS
        var orders = DeserializeOrders(xml); // XmlSerializer -> List
        SaveToLocalDb(orders); // 批次入庫
        Log.Info($"Partition {part.Start}-{part.Start+part.Count} done.");
    }
    catch (Exception ex)
    {
        Log.Error(ex, $"Partition {part.Start} failed, will retry...");
        // 重試邏輯...
    }
});

進階優化方向

結語

「大象要一口一口吃」,多執行緒分段拉取將單一巨大請求拆解為可控、可並行、可重試的小任務,是 Web Service 大量資料傳輸的經典解法。配合 Parallel/Task 與現代非同步模式,代碼更簡潔健壯。歡迎分享您的實戰調參經驗!

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
痛點優化手段
服務端單點瓶頸服務端同樣分頁查詢 + 資料庫索引優化;考慮 Read Replica 分流
網路抖動導致重傳啟用 WS-ReliableMessaging 或應用層 Checkpoint (記錄已完成分段 ID)
資料一致性若需事務一致性,採用「暫存表 + 最後合併」或分散式事務 (MSDTC)
進度監控共享 ConcurrentDictionary 記錄各分段進度,UI 輪詢顯示