2017-07-07 11 views
0

我正在使用Visual Studio生成的基於事件的代理來使用WCF服務。我遇到了一個問題,如果服務調用超時,我的應用程序將掛起。對服務的調用如下:C# - 處理基於事件的WCF代理中的錯誤例外

ServiceClient client = new ServiceClient(binding, endpointAddress); 
client.AuthenticateCompleted += (sender, e) => 
{ 
    if (e.Error != null) 
     throw e.Error; 
}; 
client.AuthenticateAsync(username, password); 

通過無數的其他問題,瀏覽,普遍的共識是,任何異常應該通過WCF被捕獲並在上面發現e.Error。但是,當我的服務超時時,情況並非如此,錯誤或者是空的,或者在我運行的其他一些測試中,應用程序在達到此代碼之前崩潰。另一位用戶建議將上述代碼封裝在try/catch塊中,但是,這樣做也無法捕獲異常。

我也嘗試在完成處理程序中放置try/catch塊,以及其他許多超出問題範圍的更復雜的方法,因爲我真的只需要以最簡單的形式繼續工作。

也值得一提的是,儘管這些故障中的很多故障發生在每個30秒的開放,關閉,發送和接收超時的實時服務中,但我也一直試圖通過將帶來的問題修復超時下降到< 1秒。我認爲這仍然會產生超時異常,並且不會導致任何其他問題,但我不是100%確定的。

我也沒有創建WCF服務,因此如果需要在服務器端執行某些特殊情況以將異常拋出回客戶端,可能會丟失此元素。如果是這樣的話,有沒有辦法解決這個問題?

回答

0

事實證明,錯誤是由IService.EndMethodName方法拋出,該方法無法通過由Visual Studio生成的類訪問。

相反,我決定直接訪問頻道,所以我對事物有更多的控制權。最終實現如下所示(IService是由Visual Studio生成的接口):

ChannelFactory<IService> factory = new ChannelFactory<IService>(binding, endpointAddress); 

// CreateChannel may not require any parameters outside of Mono 
IService channel = factory.CreateChannel(endpointAddress); 

channel.BeginAuthenticate(new AuthenticateRequest(arg0, arg1), result => 
{ 
    try 
    { 
     channel.EndAuthenticate(result); 
    } 
    catch(Exception ex) 
    { 
     throw; 
    } 
}, channel); 

這是最簡單的形式,但總的想法是,該呼叫在AsyncCallback一個try/catch內結束阻止在那裏做任何異常處理。