2012-05-26 46 views
1

我有一个监视器类,它监视设备并报告设备是否成功接收到可用数据。这可能随时发生。向代表抛出异常的习惯性方法

客户端通过传递代表创建自己的监控,启动它,并等待要么成功读取数据或者说是一种域特定的异常类型(一个基本异常型)的

什么是抛的惯用方式基本异常类型的子类型,并使客户端能够分别响应每个子类型?

public class MyMonitor 
{ 
    private SuccessHandler _successHandler; 
    private ErrorHandler _errorHandler; 
    public delegate void SuccessHandler(MyDTO result); 
    public delegate void ErrorHandler(MyBaseException exception); 

    public MyMonitor(SuccessHandler successHandler, ErrorHandler errorHandler) { 
    _successHandler = successHandler; 
    _errorHandler = errorHandler; 
    } 

    public void start() { 
    try { 
     _successHandler(new MyDTP().doSomethingRisky()); 
    } catch(Exception e) { 
     _errorHandler(e); 
    } 
    } 
} 

public class Client { 
    static void Main(string[] args) { 
    MyMonitor monitor = new MyMonitor(new MyMonitor.SuccessHandler(handleSuccess), new MyMonitor.ErrorHandler(handleException)); 
    monitor.start(); 
    } 

    static void handleSuccess(MyDTO result) { 
    // do something with result 
    } 

    static void handleException(MyBaseException e) { 
    try { 
     throw e; 
    } catch(UserException mbe) { 
     // present message to user 
    } catch(DataNotFoundException se) { 
     // log error and show generic error message 
    } catch(UnexpectedException ue) { 
     // log error and try to hide it from the user 
    } 
    } 
} 

回答

2

那么,为什么你不处理你的主,而不是监视器类的例外?

如果这是不是一种选择,你有(至少)两个选择:

static void handleException(MyBaseException e) 
{ 
    if (e is UserException) 
    { 
    // present message to user 
    } 
    else if (e is DataNotFoundException) 
    { 
    // log error and show generic error message 
    } 
    elseif (e is UnexpectedException) 
    { 
    // log error and try to hide it from the user 
    } 
    else 
    { 
    // might want to rethrow the exception, do a general handling,... 
    } 
} 

这样,你就不必重新抛出异常,就再次抓住它。 但是,这会变得非常恶劣,如果你有许多亚型处理和这里是multidispatch进来。

static void HandleException(MyBaseException e) 
{ 
    HandleSubException((dynamic)e); 
} 

static void HandleSubException(MyBaseException e) 
{ 
    // might want to rethrow the exception, do a general handling,... 
} 

static void HandleSubException(DataNotFoundExceptione) 
{ 
    // log error and show generic error message 
} 

static void HandleSubException(UnexpectedException e) 
{ 
    // log error and try to hide it from the user 
} 

static void HandleSubException(UserExceptione) 
{ 
    // present message to user 
} 

现在你可以趋向于每个异常在它自己的方法和更容易阅读和维护。说了这么多,我不完全确定这是否属于最佳做法。

+0

感谢您的建议。我同意泛型异常委托处理程序与处理Main中的异常无异。我想我会使用更具体的代表并将它们作为事件提供。这样,没有人会强制在他们的Main中处理异常,但可以选择注册一个监听器。 – rretzbach

+1

@rretzbach如果你想让它成为可选的,你应该使用事件(无需通过代表,你可以订阅它们)。例外情况应该是您的代码中需要遵守的特殊错误。现在它几乎听起来像是你想用它来控制你的程序的流程。如果存在异常,则将其抛出并在main()中处理 - 如果它只是一个通知使用事件。 – Brunner