我正在创建一个在C#中使用SOAP Web服务的应用程序。我使用svcutil
工具为Web服务WSDL生成了一个代理类。
我将代理类添加到我的代码中,并且我正在使用它来调用Web服务并获得结果异步。
当客户端具有Internet访问权限时,一切正常。但是,如果我在应用程序无法访问Internet时尝试访问,则会崩溃引发以下异常:
An exception of type 'System.ServiceModel.EndpointNotFoundException' occurred in
System.ServiceModel.Internals.dll but was not handled in user code
我正在尝试捕获此异常以防止应用程序崩溃并向用户提供更友好的错误消息,但是,由于我正在执行异步Web调用,只需通过try
围绕Web服务调用 - catch
无效。
根据异常详细信息,它发生在自动生成的代理文件中定义的End_FunctionName
函数中。
有关如何正常处理此异常的任何提示?
答案 0 :(得分:0)
很难确切地知道发生了什么;但是,我会假设你有像这样的网络服务
[ServiceContract]
public interface IMyService
{
[OperationContract]
String Hello(String Name);
[OperationContract]
Person GetPerson();
}
你可能有这样的代理:
public class MyPipeClient : IMyService, IDisposable
{
ChannelFactory<IMyService> myServiceFactory;
public MyPipeClient()
{
//This is likely where your culprit will be.
myServiceFactory = new ChannelFactory<IMyService>(new NetNamedPipeBinding(), new EndpointAddress(Constants.myPipeService + @"/" + Constants.myPipeServiceName));
}
public String Hello(String Name)
{
//But this is where you will get the exception
return myServiceFactory.CreateChannel().Hello(Name);
}
public Person GetPerson()
{
return myServiceFactory.CreateChannel().GetPerson();
}
public void Dispose()
{
((IDisposable)myServiceFactory).Dispose();
}
}
如果连接错误,当您尝试连接到频道工厂但实际尝试调用某个功能时,则不会得到它。
要解决此问题,您可以在每个函数调用周围设置try catch并手动处理异步调用。
相反,您可以使用init()等函数,每次实例化连接时都会同步调用。通过这种方式,您知道如果该呼叫连接了您有连接。
如果您有任何时候连接丢失的风险,我建议您选择以前的选项。
无论如何,这里是一个如何修复它的例子:
public class MyPipeClient : IMyService, IDisposable
{
ChannelFactory<IMyService> myServiceFactory;
public MyPipeClient()
{
myServiceFactory = new ChannelFactory<IMyService>(new NetNamedPipeBinding(), new EndpointAddress(Constants.myPipeService + @"/" + Constants.myPipeServiceName + 2) );
}
public String Hello(String Name)
{
try
{
return Channel.Hello(Name);
}
catch
{
return String.Empty;
}
}
public Person GetPerson()
{
try
{
return Channel.GetPerson();
}
catch
{
return null;
}
}
public Task<Person> GetPersonAsync()
{
return new Task<Person>(()=> GetPerson());
}
public Task<String> HelloAsync(String Name)
{
return new Task<String>(()=> Hello(Name));
}
public void Dispose()
{
myServiceFactory.Close();
}
public IMyService Channel
{
get
{
return myServiceFactory.CreateChannel();
}
}
}
我上传了我编写的源代码,以便您可以下载完整的源代码。你可以在这里得到它:https://github.com/Aelphaeis/MyWcfPipeExample
PS:此存储库会引发您获得的异常。要删除它,只需转到MyPipeClient并删除构造函数中的+ 2.
如果您使用的是双工,请考虑使用此存储库: https://github.com/Aelphaeis/MyWcfDuplexPipeExample