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

WCF 技術深度剖析(十一·上):客戶端異步調用全攻略

     編輯:關於.NET

前言:為什麼服務調用需要異步?

服務調用屬於典型的 I/O 密集型 操作(網路傳輸、序列化、等待回應)。同步阻塞會浪費寶貴的執行緒資源,降低應用程式回應性與擴展性。WCF 提供了三種異步應用場景:

  1. 異步通道調用:客戶端透過代理非同步發送訊息(本文重點)。
  2. 單向訊息交換:One-way MEP,發送即返回。
  3. 服務端異步實現:下篇詳細介紹。

三者相互獨立,可任意組合。

一、生成異步服務代理

最簡便方式:Visual Studio「加入服務參考」→「進階」→勾選「產生異步作業」。或使用 SvcUtil.exe /async。

生成的代理類(繼承 ClientBase<T>)會新增三種異步調用模式:

  • Begin/End 模式:BeginAdd/EndAdd
  • 事件模式 (EAP):AddAsync + AddComplete 事件
  • 回呼模式 (APM):BeginAdd 接受 AsyncCallback

事件參數 AddCompleteEventArgs 繼承自 AsyncCompletedEventArgs,提供 Result、Error、UserState。

二、三種異步調用方式實戰

以簡單的 CalculatorService.Add(x,y) 為例。

1. Begin/End 傳統模式

var proxy = new CalculateClient();
IAsyncResult ar = proxy.BeginAdd(1, 2, null, null);
// 執行其他工作...
double result = proxy.EndAdd(ar); // 若未完成會阻塞
proxy.Close();
Console.WriteLine($"Result: {result}");

缺點:EndAdd 可能阻塞,難以發揮真正並發優勢。

2. 回呼模式:真正的非阻塞

proxy.BeginAdd(1, 2, ar =>
{
    double[] ops = (double[])ar.AsyncState;
    double result = proxy.EndAdd(ar);
    proxy.Close();
    Console.WriteLine($"{ops[0]} + {ops[1]} = {result}");
}, new double[] { 1, 2 }); // 透過 AsyncState 傳遞上下文

優點:操作完成自動觸發回呼,主執行緒完全自由。

3. 事件註冊模式:適合 UI 程式設計

proxy.AddComplete += (sender, args) =>
{
    double[] ops = (double[])args.UserState;
    double result = args.Result;
    proxy.Close();
    Console.WriteLine($"{ops[0]} + {ops[1]} = {result}");
};
proxy.AddAsync(1, 2, new double[] { 1, 2 }); // UserState 傳遞參數

優點:符合事件驅動習慣,易於整合 WinForms/WPF/UI 線程。

關鍵提醒

  • 無論服務端是否異步實現,客戶端都可選擇異步調用。
  • 務必正確關閉代理(參見後續文章關於 Close/Abort 的最佳實踐)。
  • 異步調用不改變服務契約的傳輸協定與訊息格式。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved