0

我试图找出在 UI 端捕获 WCF 异常的最佳方法。

首先,我不得不说在调用我的服务方法时我仍然使用using,因为我的客户端代理都实现了该IDisposable.Dispose方法,如下所示:

protected virtual void Dispose(bool disposing)
{
    if (disposing)
    {
        try
        {
            if (State != CommunicationState.Faulted)
            {
                Close();
            }
        }
        finally
        {
            if (State != CommunicationState.Closed)
            {
                Abort();
            }
        }
    }
}

这允许我using在客户端代码中使用块,因为在 using 块结束时,Dispose 方法会在释放时检查通信通道的状态,如果通道处于故障状态,则中止通道。

我已经阅读了很多关于在 UI 端捕获异常的文章,实际上,我的代码如下所示:

using (var myClientProxy = new MyClientProxy())
{
    try
    {
        myClientProxy.DoSomething();
    }
    catch (TimeoutException timeoutException)
    {
        MessageBox.Show(
            timeoutException.Message, 
            "Timeout expired", 
            MessageBoxButtons.OK, 
            MesssageBoxIcon.Error);
    }
    catch (FaultException<ServiceErrorDetails> faultException)
    {
        MessageBox.Show(
            faultException.Detail.Message, 
            "A service exception occured", 
            MessageBoxButtons.OK, 
            MessageBoxIcon.Error);
    }
    catch (CommunicationException communicationException)
    {
        MessageBox.Show(
            communicationException.Message, 
            "Communication problem", 
            MessageBoxButtons.OK, 
            MessageBoxIcon.Error);
    }
    catch (Exception exception)
    {
        MessageBox.Show(
            exception.Message, 
            "An exception occured", 
            MessageBoxButtons.OK, 
            MessageBoxIcon.Error);
    }
}

如您所见,这是非常多余的,而且因为我有多个来自 UI 的 WCF 调用,这可能会成为一个很大的代码异味。

我希望能够在单个捕获块中捕获服务调用中可能出现问题的任何内容,并向用户显示一个消息框。

这是好习惯吗?因为,即使我将代码减少为单个 try/catch 块,那不还是代码异味吗?

我怎样才能更好地处理呢?

4

2 回答 2

0

如果您创建一种方法来进行尝试和捕捉,则可以重用该方法...

public void TryServiceCall(Action work)
{
  try
  {
    work();
  }
  catch1...
  catch2...
  catch3...
  catch4...
}

然后你可以这样称呼它:

using (var myClientProxy = new MyClientProxy())
{
  TryServiceCall(myClientProxy.DoSomething);
}

using (var myClientProxy = new MyClientProxy())
{
  int result;
  TryServiceCall( () => result = myClientProxy.GetFavoriteNumber() );
}
于 2013-09-03T14:34:34.163 回答
0

在这个ShowException方法中实现了如何处理和显示异常的策略

private void ShowException(Exception ex)
{
    string title ;

    if(ex is TimeoutException)
    {
        title = "Timeout expired" ;
    }
    else if(ex is FaultException)
    {
        title = "A service exception occured" ;
    }
    else if(ex is CommunicationException)
    {
        title = "Communication problem" ;
    }
    else
    {
        title = "An exception occured" ;
    }
    MessageBox.Show(ex.Message, title,MessageBoxButtons.OK, MesssageBoxIcon.Error);
}

然后在您的代码的任何方法中,您都像这样使用它

private void AnyMethod()
{
    ....
    using (var myClientProxy = new MyClientProxy())
    {
        try
        {
            myClientProxy.DoSomething();
        }
        catch (Exception ex)
        {
            ShowException(ex) ;
        }
    }
    ....
}

如果您想使用日志记录并修改如何处理异常,您只需要更改ShowException方法

于 2013-09-03T14:34:46.970 回答