简体   繁体   English

处理代理中的错误 - WCF

[英]Handling errors within a proxy - WCF

A good suggestion on how to handle errors within a Client can be found here .可以在此处找到有关如何处理客户端错误的好建议。
Copying here for easy access:在这里复制以方便访问:

MyServiceClient myServiceClient = new MyServiceClient();

try
{
    documents = myServiceClient.GetDocuments();
    // More code that isn't useful including here ...
    myServiceClient.Close();
}
catch (TimeoutException exception)
{
    MessageBox.Show(exception.Message, "Timeout error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    myServiceClient.Abort();
}
catch (FaultException<ServiceErrorDetails> error)
{
    MessageBox.Show(error.Detail.Message, "Service error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    myServiceClient.Abort();
}
catch (CommunicationException exception)
{
    MessageBox.Show(exception.Message, "Communication error", MessageBoxButtons.OK, MessageBoxIcon.Error);
    myServiceClient.Abort();
}

Now the problem I am having with this solution is that my Proxy contains many many methods.现在我遇到的这个解决方案的问题是我的代理包含许多方法。 Easy to understand I would rather not want to add this huge try/catch statement around all my method calls.易于理解我不想在我所有的方法调用周围添加这个巨大的 try/catch 语句。
Instead, I thought it could be a good idea to add the error handling from within MyServiceClient() class.相反,我认为从 MyServiceClient() class 中添加错误处理可能是个好主意。
But the question is how to do that without polluting all the Methods here again with this try/catch statement?但问题是如何做到这一点,而不用这个 try/catch 语句再次污染这里的所有方法?
How would you approach that?你会怎么处理呢?

You could try encapsulating the try/catch logic in a handler class as follows:您可以尝试将 try/catch 逻辑封装在处理程序 class 中,如下所示:

public static class Example
{
    public static void ExecuteExample()
    {
        var serviceClient = new ServiceClient();

        var documents = ProxyErrorHandler.Execute(serviceClient, serviceClient.GetDocuments);
    }
}

public static class ProxyErrorHandler
{
    public static void Execute(ServiceClient serviceClient, Action actionToExecute)
    {
        Execute(serviceClient, () =>
        {
            actionToExecute();

            return true;
        });
    }

    public static T Execute<T>(ServiceClient serviceClient, Func<T> functionToExecute)
    {
        try
        {
            return functionToExecute();
        }
        catch (Exception exception)
        {
            ShowException(serviceClient, exception);

            return default;
        }
    }

    public static Task ExecuteAsync(ServiceClient serviceClient, Func<Task> actionToExecute)
    {
        return ExecuteAsync(serviceClient, async () =>
        {
            await actionToExecute();

            return true;
        });
    }

    public static async Task<T> ExecuteAsync<T>(ServiceClient serviceClient, Func<Task<T>> functionToExecute)
    {
        try
        {
            return await functionToExecute();
        }
        catch (Exception exception)
        {
            ShowException(serviceClient, exception);

            return default;
        }
    }

    private static void ShowException(ServiceClient serviceClient, Exception exception)
    {
        string title;
        var message = exception.Message;

        switch (exception)
        {
            case TimeoutException:
                title = @"Timeout error";
                break;
            case FaultException<ServiceErrorDetails> faultException:
                title = @"Service error";
                message = faultException.Detail.Message;
                break;
            case CommunicationException:
                title = @"Communication error";
                break;
            default:
                ExceptionDispatchInfo.Throw(exception);
                
                // Unreachable
                throw new Exception();
        }

        MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error);

        serviceClient.Abort();
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM