即使在try/catch块中,也会解除CommunicationException
本文关键字:CommunicationException 块中 try catch | 更新日期: 2023-09-27 18:19:25
我目前正在为WP7开发一个需要调用WCF服务应用程序的应用程序。我用一个小的WPF应用程序测试了该服务,一切都很顺利。但现在我从我的WP7应用程序中调用它,我系统地得到了以下异常:
An exception of type 'System.ServiceModel.CommunicationException' occurred in
System.ServiceModel.ni.dll but was not handled in user code
System.ServiceModel.CommunicationException was unhandled by user code
HResult=-2146233087
Message=The remote server returned an error: NotFound.
Source=System.ServiceModel
InnerException: System.Net.WebException
HResult=-2146233079
Message=The remote server returned an error: NotFound.
Source=System.Windows
InnerException: System.Net.WebException
HResult=-2146233079
Message=The remote server returned an error: NotFound.
Source=System.Windows
InnerException:
尽管我在这样的try/catch块中(在MyProjectPath.Model.User.cs中)进行了服务调用,但异常仍在不断解除:
public Task<User> Load(string logon, string pwHash)
{
TaskCompletionSource<User> tcs = new TaskCompletionSource<User>();
client.GetUserByCredsCompleted += ((s, e) =>
{
if (e.Error == null) tcs.TrySetResult(e.Result);
else
{
StringBuilder sb = new StringBuilder();
sb.AppendLine("Error encountered while getting data :");
sb.AppendLine(e.Error.Message);
MessageBox.Show(sb.ToString());
}
});
try
{
client.GetUserByCredsAsync(logon, pwHash);
}
catch (System.ServiceModel.CommunicationException ex)
{
MessageBox.Show(ex.Message);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
return tcs.Task;
}
当执行时,异常发生在这里(在System.ServiceModel.ni.dll中):
public MyProjectPath.ServiceReference.User EndGetUserByCreds(System.IAsyncResult result) {
object[] _args = new object[0];
// Exception gets lifted by the following line :
MyProjectPath.ServiceReference.User _result = ((MyProjectPath.ServiceReference.User)(base.EndInvoke("GetUserByCreds", _args, result)));
return _result;
}
有人已经遇到并解决了这个问题吗?我必须承认我在这里很无知。。。
您正在调用一个异步API。尽管您将该调用封装在try/catch块中,但该调用可能会启动一个新线程或排队请求另一个现有线程。无论哪种方式,您的try/catch只是保护您免受在进行调用的线程上抛出的异常的影响,而没有任何异常。异步调用的(启动)非常成功,所以catch块永远不会生效,然后控制权被传递给另一个线程,这就是抛出异常的地方。
您无法通过在try/catch中包装对GetUserByCredssync的调用来防止EndGetUserByCreds中出现异常。这两种方法在不同的时间执行不同的线程。您需要修改EndGetUserByCreds,以便它捕获异常并对其进行适当处理,而不是让它们破坏线程。