添加全局尝试捕获例外

时间:2013-07-18 04:41:30

标签: c#

我以这种方式实现了Global Try Catch机制。我添加了一个名为HandleException.cs

的单独类
public static class HandleException
{
    public static void GlobalTryCatch(Action action, object obj)
    {
        try
        {
            action.Invoke();
        }
        catch(SqlException ex)
        {
            obj.GetType().GetProperty("Success").SetValue(obj.GetType(), false);
            obj.GetType().GetProperty("FailureMessage").SetValue(obj.GetType(), ex);
        }
        catch(Exception ex)
        {
            obj.GetType().GetProperty("Success").SetValue(obj.GetType(), false);
            obj.GetType().GetProperty("FailureMessage").SetValue(obj.GetType(), ex);
        }
    }
}

这样称呼它。

public override Result<int> Update(UserProfile data)
    {

        var result = new Result<int> { Success = false };

        HandleException.GlobalTryCatch(() =>
                                           {
                                               SqlParameter[] sParam =
                                                   {
                                                       DbHelper.CreateParameter("@UserId", ParameterDirection.Input, SqlDbType.Int, data.UserId),
                                                       DbHelper.CreateParameter("@FirstName", ParameterDirection.Input, SqlDbType.VarChar,100, data.FirstName),
                                                       DbHelper.CreateParameter("@LastName", ParameterDirection.Input, SqlDbType.VarChar,100, data.LastName),
                                                       DbHelper.CreateParameter("@Gender", ParameterDirection.Input, SqlDbType.Char,1, data.Gender),
                                                       DbHelper.CreateParameter("@Dob", ParameterDirection.Input, SqlDbType.Date, data.DateOfBirth),
                                                       DbHelper.CreateParameter("@ImageUrl", ParameterDirection.Input, SqlDbType.VarChar, 150, data.ImageUrl),
                                                   };

                                               using(var sql = new DbHelper())
                                               {
                                                   sql.ExecuteSpReturnScalar("UserProfile_Update", sParam);
                                               }
                                               result.Success = true;
                                           }, result);
        return result;

}

我的问题是

  1. 这是实现全局try catch机制的标准做法还是有其他标准方法来实现它?
  2. 我在GlobalTryCatch方法中使用了它。这种方式我们可以通过传递Generic Object来为属性赋值吗?

    obj.GetType()。GetProperty(“Success”)。SetValue(obj.GetType(),false);

2 个答案:

答案 0 :(得分:4)

  

这是实现全局尝试捕获机制的标准做法

不,不是。而且,提到的“全球试捕机制”是一种不好的做法。在try-catch中包含每个方法假设,您肯定知道,在抛出任何异常后该怎么做。在现实世界中,这是错误的。看看这个样本:

void AnyMethod()
{
    var result = // ...

    HandleException.GlobalTryCatch(() => { /* action 1 */}, result);

    // should we check result to continue?
    // if so, this is a typical error-code approach, which annihilates 
    // all preferences, provided by .NET exceptions;
    // if we shouldn't check it, what would be the behavior of our code,
    // if the state is broken after action 1? 

    HandleException.GlobalTryCatch(() => { /* action 2 */}, result);

    // the same questions

    HandleException.GlobalTryCatch(() => { /* action 3 */}, result);
}

用于记录异常的类似方法(由于缺少.NET中的现成方面):

void Execute(Action action)
{
    try
    {
        action();
    }
    catch (Exception e)
    {
        Logger.Log(e);
        throw;
    }
}

T Execute<T>(Func<T> func)
{
    try
    {
        return func();
    }
    catch (Exception e)
    {
        Logger.Log(e);
        throw;
    }
}

但:
1)它记录完整的异常信息(例如,您的代码缺少堆栈跟踪和内部异常);
2)它重新抛出相同的异常(这允许使用.NET异常的所有好处);
3)它只包含有限数量的顶级方法,而不是每种方法。

  

我是否可以通过传递Generic Object为属性赋值?

你可以这样做:

interface IActionResult
{
    bool Success { get; set; }
    string FailureMessage { get; set; }
}

public static void GlobalTryCatch<T>(Action action, T obj)
    where T : IActionResult
{
    // ...
}

但这不会取消你第一个问题的答案。

答案 1 :(得分:3)

您可以使用http://msdn.microsoft.com/en-us/library/system.appdomain.unhandledexception.aspx(或http://msdn.microsoft.com/en-us/library/system.windows.application.dispatcherunhandledexception.aspx用于WPF应用程序。)

通常,在此事件期间执行有意义的操作并不是一个坏主意 - 记录异常(或将其发送给管理员)并向用户显示消息(例如“抱歉,发生错误,请联系管理员”)。

但正如其他人所说 - 你应该处理你的方法中的一些事情,你可以用它们做一些有意义的事情,而不是在全球范围内。即使它在c#中不是强制性的,最好在注释中添加你的方法在某些情况下会抛出某种异常。

相关问题