服務調用屬於典型的 I/O 密集型 操作(網路傳輸、序列化、等待回應)。同步阻塞會浪費寶貴的執行緒資源,降低應用程式回應性與擴展性。WCF 提供了三種異步應用場景:
三者相互獨立,可任意組合。
最簡便方式:Visual Studio「加入服務參考」→「進階」→勾選「產生異步作業」。或使用 SvcUtil.exe /async。
生成的代理類(繼承 ClientBase<T>)會新增三種異步調用模式:
BeginAdd/EndAddAddAsync + AddComplete 事件BeginAdd 接受 AsyncCallback事件參數 AddCompleteEventArgs 繼承自 AsyncCompletedEventArgs,提供 Result、Error、UserState。
以簡單的 CalculatorService.Add(x,y) 為例。
var proxy = new CalculateClient();
IAsyncResult ar = proxy.BeginAdd(1, 2, null, null);
// 執行其他工作...
double result = proxy.EndAdd(ar); // 若未完成會阻塞
proxy.Close();
Console.WriteLine($"Result: {result}");
缺點:EndAdd 可能阻塞,難以發揮真正並發優勢。
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 傳遞上下文
優點:操作完成自動觸發回呼,主執行緒完全自由。
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 的最佳實踐)。