我是DRY編碼的忠實粉絲,我喜歡儘可能避免使用鍋爐板代碼。因此,我將所有WCF頻道faff重構爲一個AOP類,它處理WCF頻道的生命週期。return await Method.Invoke()
我也是異步等待的狂熱粉絲,尤其是在WCF中,因爲它理論上會釋放一個通常會等待響應的線程。
所以我創造了fluentAOP一個攔截器的lib
private static object InvokeOnChannel(IMethodInvocation methodInvocation)
{
var proxy = _factory.CreateChannel();
var channel = (IChannel) proxy;
try
{
channel.Open();
var ret = methodInvocation.Method.Invoke(proxy, methodInvocation.Arguments);
channel.Close();
return ret;
}
catch (FaultException ex)
{
if (ex.InnerException != null)
throw ex.InnerException;
throw;
}
catch(Exception)
{
channel.Abort();
throw;
}
}
然而,想介紹一下我提到的解決方案時,在形式的WCF合同的情況下
[ServiceContract]
public interface IFoo
{
[OperationContract]
Task<int> GetInt();
}
GetInt會有意想不到的結果。首先,捕獲FaultException將不會執行任何操作。其次,我會在請求返回之前關閉頻道。如果返回類型是Task,我理論上可以切換到另一個代碼路徑。但我無法弄清楚如何等待任務<>的結果,然後返回等待狀態。
這當然是特別困難的,因爲使用運行時AOP,我不能訪問能夠使用返回類型的泛型(沒有整個反射)。
任何想法如何實現這個函數作爲一個awaitable,它關閉完成通道和捕獲/編組異常到調用線程?
該死的。和我想的一樣。必須使用通用get方法。 – Aron 2013-03-04 14:01:53
我正在玩'動態'功能,看看我是否可以進一步簡化這一點,但目前看起來並不樂觀。 – 2013-03-04 14:03:23
不是動態的大粉絲,如果僅僅因爲你必須引用CSharp庫。無論如何,看起來像你的代碼是最好的...做一種希望C#對元編程有點更好。 – Aron 2013-03-05 03:06:15