对wcf调用重用try catch

本文关键字:try catch wcf 调用 | 更新日期: 2023-09-27 18:02:08

我有一系列调用wcf服务的方法,它们都有相同的try catch代码

Response Method1(Request request)
{
    Response response = null;
    using(ChannelFactory<IService1> factory = new ChannelFactory<IService1>(myEndpoint))
    {
        IService1 channel = factory.CreateChannel();
        try
        {
            response = channel.Operation(request);
        }
        catch(CommunicationException ex)
        {
            // Handle Exception
        }
        catch(TimeoutException ex)
        {
            // Handle Exception
        }
        catch(Exception ex)
        {
            // Handle Exception
        }
    }
    return response;
}

等等(对于不同的服务,我有6个这样的方法)…如何在一个方法中封装所有的服务调用并处理异常?

编辑

根据Nathan A的建议,我创建了一个简单的泛型方法:

protected TResult ExecuteAndCatch<TResult>(Func<T, TResult> serviceCall, T request)
    where T : Request
    where TResult : Response
{
    try
    {
        return serviceCall(request);
    }
    catch (CommunicationException ex)
    {
    }
    catch (TimeoutException ex)
    {
    }
    catch (Exception ex)
    {
    }
    return null;
}

新方法是这样的

Response NewMethod1(Request request)
{
    Response response = null;
    using(ChannelFactory<IService1> factory = new ChannelFactory<IService1>(myEndpoint))
    {
        IService1 channel = factory.CreateChannel();
        response = channel.Operation(request);
    }
    return response;
}

我试着把它命名为

Response response = ExecuteAndCatch<Response>(NewMethod1, new Request())

我做错了什么?

对wcf调用重用try catch

使用包装器函数。

看看这篇文章:http://mytenpennies.wikidot.com/blog:writing-wcf-wrapper-and-catching-common-exceptions

下面是文章中的一个例子:

private void ExecuteAndCatch<T> (Action<T> action, T t) {
    try {
        action (t);
        Success = true;
    }
    catch (TimeoutException) {
        Success = false;
        Message = "Timeout exception raised.";
    }
    catch (CommunicationException) {
        Success = false;
        Message = "Communication exception raised.";
    }
}

如果您的客户端来自ClientBase<T>,例如MyClient : ClientBase<IWCFService>

然后,您可以创建自己的基类,该基类提供包装公共功能的方法。

下面的示例代码可以扩展,以允许最终的派生类指定当特定方法调用失败时该做什么。这里我只调用HandleError

在特定的客户端类

//method that returns a value
public int Ping()
{
    return Protect(c => c.Ping());
}    
//void method usage
public void Nothing(int stuff)
{
    Protect(c => c.Nothing(stuff));
}      

在客户基类

protected void Protect(Action<IWCFService> action)
{
    Protect(c => { action(c); return true; });
}
//add other exception handling
protected Protect<T>(Func<IWCFService, T> func)
{
    try
    {
        return func(Channel);
    }
    catch (FaultException e)
    {
        HandleError(e);//up to you to implement this and any others
    }
    return default(T);
}

通过一个接口注入各种客户端,然后在一个地方运行操作?

HttpResponse performOperation(IServiceClient injectedServiceClient)
{
    IServiceClient client = injectedServiceClient;
    try
    {
        client.Operation();
    }
    catch(CommunicationException ex)
    {
        // Handle Exception
    }
    catch(TimeoutException ex)
    {
        // Handle Exception
    }
    catch(Exception ex)
    {
        // Handle Exception
    }
    return httpResponse(httpStatusCode.OK);
}