【问题标题】:Catching " 'System.ServiceModel.EndpointNotFoundException' Exception happening during asynchronous web service call在异步 Web 服务调用期间捕获“'System.ServiceModel.EndpointNotFoundException' 异常
【发布时间】:2014-07-08 10:47:18
【问题描述】:

我正在创建一个使用 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 调用,只需将 Web 服务调用用 try-@ 包围987654325@ 没有帮助。

根据异常详细信息,它发生在自动生成的代理文件中定义的End_FunctionName 函数中。

关于如何优雅地处理此异常的任何提示?

【问题讨论】:

标签: c# web-services wcf soap exception-handling


【解决方案1】:

很难确切地知道发生了什么;但是,我假设您有这样的网络服务

[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。

如果您使用的是 Duplex,请考虑使用此存储库: https://github.com/Aelphaeis/MyWcfDuplexPipeExample

【讨论】:

    猜你喜欢
    • 2020-09-25
    • 2011-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-15
    • 2011-09-03
    相关资源
    最近更新 更多