处理代理中的错误 - WCF

Handling errors within a proxy - WCF

可以找到有关如何在客户端中处理错误的好建议 here
复制到这里方便访问:

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

现在我在这个解决方案中遇到的问题是我的代理包含很多很多方法。易于理解我不想在我的所有方法调用周围添加这个巨大的 try/catch 语句。
相反,我认为从 MyServiceClient() class.
中添加错误处理可能是个好主意 但问题是如何做到这一点而不用这个 try/catch 语句再次污染这里的所有方法?
你会如何处理?

您可以尝试将 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();
    }
}