我正在尝试编写一个封装 WCF 调用的类(如果重要,客户端是 Silverlight)。这一切都很顺利,但我不确定如何捕获连接失败,就好像服务器不会响应一样。似乎在 ChannelFactory 生成的代码中某处发生了一些工作,但我不确定。也欢迎一般的代码审查。:)
底线,围绕通道的创建,或者 try/catch 中的开始或异步结果委托不会捕获失败的连接。我想让那个 catch 运行 ServiceCallError 事件。
public class ServiceCaller : IDisposable
{
private IFeedService _channel;
public ServiceCaller()
{
var elements = new List<BindingElement>();
elements.Add(new BinaryMessageEncodingBindingElement());
elements.Add(new HttpTransportBindingElement());
var binding = new CustomBinding(elements);
var endpointAddress = new EndpointAddress(App.GetRootUrl() + "Feed.svc");
_channel = new ChannelFactory<IFeedService>(binding, endpointAddress).CreateChannel();
}
public void MakeCall(DateTime lastTime, Dictionary<string, string> context)
{
AsyncCallback asyncCallBack = delegate(IAsyncResult result)
{
var items = ((IFeedService)result.AsyncState).EndGet(result);
if (ItemsRetrieved != null)
ItemsRetrieved(this, new ServiceCallerEventArgs(items));
};
_channel.BeginGet(lastTime, context, asyncCallBack, _channel);
}
public event ItemsRetrievedEventHandler ItemsRetrieved;
public event ServiceCallErrorHandler ServiceCallError;
public delegate void ItemsRetrievedEventHandler(object sender, ServiceCallerEventArgs e);
public delegate void ServiceCallErrorHandler(object sender, ServiceCallErrorEventArgs e);
public void Dispose()
{
_channel.Close();
_channel.Dispose();
}
}
这是堆栈跟踪,对于那些好奇的人:
An AsyncCallback threw an exception.
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously, Exception exception)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.OnGetResponse(IAsyncResult result)
at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClassd.<InvokeGetResponseCallback>b__b(Object state2)
at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)
为此,我在浏览器中启动应用程序,然后从 Visual Studio 中终止 Web 服务器进程。在测试环境中,我通过终止客户端系统的网络连接得到同样的结果。
这是完整异常的 ToString():
System.Exception: An AsyncCallback threw an exception. ---> System.Exception: An AsyncCallback threw an exception. ---> System.ServiceModel.CommunicationException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound. ---> System.Net.WebException: The remote server returned an error: NotFound.
at System.Net.Browser.BrowserHttpWebRequest.InternalEndGetResponse(IAsyncResult asyncResult)
at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClass5.<EndGetResponse>b__4(Object sendState)
at System.Net.Browser.AsyncHelper.<>c__DisplayClass2.<BeginOnUI>b__0(Object sendState)
--- End of inner exception stack trace ---
at System.Net.Browser.AsyncHelper.BeginOnUI(SendOrPostCallback beginMethod, Object state)
at System.Net.Browser.BrowserHttpWebRequest.EndGetResponse(IAsyncResult asyncResult)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.CompleteGetResponse(IAsyncResult result)
--- End of inner exception stack trace ---
at System.ServiceModel.Channels.Remoting.RealProxy.Invoke(Object[] args)
at proxy_2.EndGet(IAsyncResult )
at CoasterBuzz.Feed.Client.ServiceCaller.<MakeCall>b__0(IAsyncResult result)
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
--- End of inner exception stack trace ---
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously, Exception exception)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.CallComplete(Boolean completedSynchronously, Exception exception)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.FinishSend(IAsyncResult result, Boolean completedSynchronously)
at System.ServiceModel.Channels.ServiceChannel.SendAsyncResult.SendCallback(IAsyncResult result)
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
--- End of inner exception stack trace ---
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously)
at System.ServiceModel.AsyncResult.Complete(Boolean completedSynchronously, Exception exception)
at System.ServiceModel.Channels.HttpChannelFactory.HttpRequestChannel.HttpChannelAsyncRequest.OnGetResponse(IAsyncResult result)
at System.Net.Browser.BrowserHttpWebRequest.<>c__DisplayClassd.<InvokeGetResponseCallback>b__b(Object state2)
at System.Threading._ThreadPoolWaitCallback.WaitCallback_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallbackInternal(_ThreadPoolWaitCallback tpWaitCallBack)
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback(Object state)
顺便说一句,我能抓住这一点的唯一方法是在 SL 客户端中使用应用程序级别的 UnhandledException 事件。