重用try catch进行wcf调用

时间:2014-05-07 17:23:30

标签: c# .net wcf exception-handling .net-3.5

我有一系列调用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())

我做错了什么?

3 个答案:

答案 0 :(得分:3)

使用包装函数。

看一下这篇文章: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.";
    }
}

答案 1 :(得分:1)

如果您的客户来自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);
}

答案 2 :(得分:0)

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

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);
}