WCF 服務擴展性受兩大因素影響:併發模式決定單一實例如何處理多執行緒,實例模式決定建立多少實例,節流設定限制系統資源上限。三者結合決定服務吞吐量與資源消耗。
| 模式 | 行為 | 適用場景 |
|---|---|---|
| Single (預設) | 單一執行緒存取實例,系統自動加鎖 | 狀態型服務、非執行緒安全元件 |
| Reentrant | 單執行緒但允許重入(回調時釋放鎖) | 雙工回調服務,避免死鎖 |
| Multiple | 多執行緒同時存取,需自行同步 | 高併發無狀態服務、自行管理鎖 |
| 模式 | 實例生命週期 |
|---|---|
| PerCall | 每次呼叫建立新實例,呼叫結束回收 |
| PerSession (預設) | 每個 Session 一個實例 |
| Single | 全域單一實例,所有呼叫共享 |
| Instance \ Concurrency | Single | Reentrant | Multiple |
|---|---|---|---|
| PerCall | 無併發問題 (每呼叫新實例) | 無併發問題 | 無併發問題 |
| PerSession | Session 內單執行緒 | Session 內可重入 | Session 內多執行緒,有併發問題 |
| Single | 全域單執行緒 | 全域可重入 | 全域多執行緒,有併發問題 |
[ServiceContract(CallbackContract = typeof(IDuplexReentrantCallback))]
public interface IDuplexReentrant {
[OperationContract] void HelloDuplexReentrant(string name);
}
public interface IDuplexReentrantCallback {
[OperationContract] void HelloDuplexReentrantCallback(string name);
}
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Reentrant)]
public class DuplexReentrant : IDuplexReentrant {
public void HelloDuplexReentrant(string name) {
var callback = OperationContext.Current.GetCallbackChannel<IDuplexReentrantCallback>();
callback.HelloDuplexReentrantCallback(name); // 回調時釋放鎖,允許重入
}
}
若使用 Single 模式,回調返回服務時會因鎖被佔用而死鎖。Reentrant 讓回調執行緒進入佇列尾部等待,避免死鎖。
[CallbackBehavior(UseSynchronizationContext = false)]
public class ReentrantCallbackType : IDuplexReentrantCallback {
public void HelloDuplexReentrantCallback(string name) {
MessageBox.Show("Hello: " + name);
}
}
UseSynchronizationContext = false 讓回調不綁定 UI 執行緒,避免跨執行緒 UI 存取問題。
在 <serviceBehaviors> 中設定:
<serviceThrottling
maxConcurrentCalls="16" <!-- 同時處理的訊息數,預設 16 -->
maxConcurrentInstances="2147483647" <!-- 同時存在的實例數,預設 Int32.MaxValue -->
maxConcurrentSessions="10" <!-- 同時 Session 數,預設 10 -->
/>
<!-- PerCall:限制同時呼叫數,實例數跟隨 -->
<behavior name="BehaviorPerCall">
<serviceThrottling maxConcurrentCalls="100" maxConcurrentInstances="100" />
</behavior>
<!-- PerSession:限制 Session 數 -->
<behavior name="BehaviorPerSession">
<serviceThrottling maxConcurrentSessions="200" />
</behavior>
<!-- Single:實例數固定為 1 -->
<behavior name="BehaviorSingle">
<serviceThrottling maxConcurrentInstances="1" />
</behavior>
PerCall + Multiple + 增加 maxConcurrentCallsPerSession + Single/Reentrant + 設定 maxConcurrentSessionsSingle + Multiple + 自行同步 + maxConcurrentInstances=1PerSession/Single + Reentrant + CallbackBehavior(UseSynchronizationContext=false)ServiceModelService 4.0.0.0 → Calls Outstanding、Instances CreatedServiceThrottling 拒絕事件(超過限制時會擲回 ServerTooBusyException)正確配置併發模式、實例模式與節流參數,是 WCF 服務從「能跑」到「跑得快、穩得住」的關鍵。