【问题标题】:Problem with a trycatch functiontrycatch 函数的问题
【发布时间】:2011-07-05 10:13:40
【问题描述】:

我有 2 节课。使用通用数据访问类,我可以从存储过程 GetDepartments 中获取部门。我的问题是在目录访问类中,特别是在公共静态 DataTable ExecuteSelectCommand(DbCommand 命令)(执行命令并将结果作为 DataTable 对象返回)我不知道我必须在 CATCH 循环中写什么或如何离开它空白。任何人都可以帮我完成这部分吗?或者如果没有 Try-catch,我该如何更改它。

using System;    
using System.Data;    
using System.Data.Common;    
using System.Configuration;    

public static class GenericDataAccess    
{    
  static GenericDataAccess()
  {

  }


  public static DataTable ExecuteSelectCommand(DbCommand command)    
  {    
    DataTable table;

    try    
    { 

      command.Connection.Open();    
      DbDataReader reader = command.ExecuteReader();    
      table = new DataTable();          
      table.Load(reader);          
      reader.Close();        
    }    
    catch (...)    
    {    
      ......
    }    
    finally    
    {         
      command.Connection.Close();    
    }

    return table;    
  }

  public static DbCommand CreateCommand()    
  {    
    string dataProviderName = BalloonShopConfiguration.DbProviderName;   
    string connectionString = BalloonShopConfiguration.DbConnectionString;

    DbProviderFactory factory = DbProviderFactories.GetFactory(dataProviderName);    
    DbConnection conn = factory.CreateConnection();

    conn.ConnectionString = connectionString;

    DbCommand comm = conn.CreateCommand();    
    comm.CommandType = CommandType.StoredProcedure;

    return comm;
  }
}

**The Catalog Access class:**

using System;    
using System.Data;    
using System.Data.Common;

public static class CatalogAccess    
{    
  static CatalogAccess()
  {

  }

  public static DataTable GetDepartments()    
  {    
    DbCommand comm = GenericDataAccess.CreateCommand();

    comm.CommandText = "GetDepartments";

    return GenericDataAccess.ExecuteSelectCommand(comm);    
  }    
}

【问题讨论】:

  • 如果您的 ExecuteSelectCommand 方法发生异常,您想做什么?这将决定需要进入 catch 块的内容。
  • 阅读器必须在里面使用。
  • 看起来 Connection 可能同样被泄露。

标签: c# exception-handling data-access-layer


【解决方案1】:

如果您不知道该做什么或不想处理任何异常,请留下catch。这是有效的:

try
{
    // code here
}
finally
{
    // cleanup here
}

..这样,任何异常都将传递给调用您的方法的方法。如果try 块中出现问题(异常),该方法将退出,但不会在finally 中的任何代码执行之前退出。

【讨论】:

  • 当我尝试您提出的第二种方式时,出现此错误“无法打开登录请求的数据库“BalloonShop”。登录失败。'。错误在这一行“command.Connection.Open();”
  • @theo1985,您使用的连接字符串可能不正确。检查您是否连接到正确的数据库服务器并且该服务器具有BalloonShop 数据库。
【解决方案2】:

在处理异常时,您有两种选择:您可以在它们被抛出时立即处理它们,或者您可以让它们冒泡代码并在以后处理它们。哪个更好取决于您的程序到底是做什么的。

您如何处理它还取决于您的代码。您要通知用户吗?重试连接?两个都?什么都不做(坏事!)?假设您只想让用户知道发生了不好的事情。然后你会做如下的事情:

try{
    // breakable stuff
}catch(Exception e){
    System.Windows.Forms.MessageBox.Show("Something broke:  " + e.Message);
}finally{
    // clean up
}

如果您想进一步处理异常(也就是在调用此异常的方法中),请执行以下操作:

try{
    // breakable stuff
}catch{
    throw;
}finally{
    // clean up
}

【讨论】:

  • catch { throw; } 没有添加任何有价值的东西,除了可能放置断点的行。但它可能应该在#if DEBUG 部分内。
  • 没错,但它也不会伤害任何东西,而且 IMO 它使它更具可读性,并且更清楚地了解到底发生了什么。
  • 对此感到抱歉 :´( 再一次,您当然是正确的,但是(正如您所说)对于 OP 的代码,删除 catch 在性能方面与删除一样有用所有 cmets 以减少编译时间:D
  • 我做了一个更好的基准测试,但没有得到任何结论性的结果。哎呀。所以我刚刚删除了我之前关于性能的评论。
  • 如果编译器添加了 catch { throw; } 的幕后等效项,如果它没有找到用户定义的 catch 块(有点像默认构造函数),我不会感到惊讶,但是我不确定,不幸的是现在没有时间去研究它......
【解决方案3】:

我不确定要问什么,但我怀疑你不想在你的函数中处理异常,而是让它沿着堆栈传播(即让调用者处理它)。

要实现这一点,您只需将catch-clause 从您的代码中删除即可。 finally 下面的代码仍然会被调用。如果您希望在函数中处理异常,但在返回之前重新抛出它,请尝试:

catch (MyException e)
{
   // Do stuff with e
   throw;
}

【讨论】:

  • 您会因此丢失堆栈跟踪信息。更好的是throw;
  • 这样做会给你一个关于未使用变量e的编译器警告,所以如果你要做的就是再次抛出它,那么catch { throw; }会更好。或者,如果您不介意可读性的轻微损失,则根本没有 catch 块......
  • @elmugrat: Not if // Do stuff with e 实际上做了一些事情。对于另一种情况,就像我在回答中指出的那样(以及您在评论中指出的),只留下 catch-clause 会更好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-07
  • 2021-12-04
  • 2018-10-02
  • 2018-05-31
  • 1970-01-01
  • 2017-07-27
相关资源
最近更新 更多