在UI端捕获WCF异常

时间:2013-09-03 14:22:18

标签: c# wcf exception-handling

我正在尝试找出在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块,因为在使用块结束时,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调用,这可能会成为一个非常大的代码味道。

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

这是好的做法吗?因为,即使我将代码减少到单个try / catch块,这仍然不是代码味道吗?

我怎样才能更好地处理?

2 个答案:

答案 0 :(得分: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() );
}

答案 1 :(得分: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 方法