0

我以这种方式实现了一个全局 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方法中使用过这个。这样我们是否可以通过传递通用对象来为属性赋值?

    obj.GetType().GetProperty("Success").SetValue(obj.GetType(), false);

4

2 回答 2

4

这是实现全局 try catch 机制的标准做法吗

不它不是。此外,提到的“全局 try-catch 机制”是一种不好的做法。包装每个方法都假定,你肯定知道,在抛出任何异常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)它只包含有限数量的顶级方法,而不是每个方法。

这样我们是否可以通过传递通用对象来为属性赋值?

你可以这样做:

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

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

但这不会取消您对第一个问题的回答。

于 2013-07-18T05:02:28.077 回答
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# 中它不是强制性的,在注释中添加您的方法可以在某些情况下抛出某种异常也是一个好主意。

于 2013-07-18T04:59:28.657 回答