使用返回Task <int>的ExecuteNonQueryAsync时捕获和抛出错误

时间:2016-02-01 17:47:17

标签: c# async-await sqlconnection sqlcommand try-catch-finally

当我执行以下操作时,我收到警告,如果catch块没有返回int,则并非所有代码路径都返回值;当该catch块返回一个int时,除非将其置于finally块内,否则对该null的capturedException测试将无法访问。最终投掷内线是否可以接受?连接是否自动关闭,就像采用using语法的同步方法一样?

public async Task<int> Write2Log()
{
  ExceptionDispatchInfo capturedException = null;
  using (SqlConnection conn = new SqlConnection(connectionString))
  {                   
      using (SqlCommand cmd = new SqlCommand(commandText, conn))
      {
         try
           {
         await cmd.Connection.OpenAsync();
         return await cmd.ExecuteNonQueryAsync();
            }
           catch (Exception ex)
             {
               capturedException=ExceptionDispatchInfo(ex);
               return -1;
             }

             // unreachable unless placed inside `finally` block
            if (capturedException != null)
              {
                   capturedException.Throw();
              }

      }


  }
}

2 个答案:

答案 0 :(得分:0)

你的代码似乎是不正确的,但无论如何你不需要在catch中返回.....你可以在方法的最后返回。你知道成功的场景永远不会到达方法的终点。

public async Task<int> Write2Log()
{
  ExceptionDispatchInfo capturedException = null;
  using (SqlConnection conn = new SqlConnection(connectionString))
  {                   
      using (SqlCommand cmd = new SqlCommand(commandText, conn))
      {

          try
{
         await cmd.Connection.OpenAsync();
         return await cmd.ExecuteNonQueryAsync();
}
           catch (Exception ex)
             {
               capturedException=ExceptionDispatchInfo(ex);

             }

             // unreachable unless placed inside `finally` block
            if (capturedException != null)
              {
                   capturedException.Throw();
              }

      }


  }
   return -1;
}

答案 1 :(得分:0)

你笨拙地试图写的代码等同于更简单的代码

public async Task<int> Write2Log()
{
  using (var conn = new SqlConnection(connectionString))
  {
    using (var cmd = new SqlCommand(commandText, conn)
    {
      await conn.OpenAsync();
      return await cmd.ExecuteNonQueryAsync();
    }
  }
}

如果你不明白为什么,你可能想要了解.NET异常如何工作的知识,以及await如何工作(特别是它如何处理异常)。

如果您还想观察异常(例如,记录日志),您可以使用throw;catch的末尾重新抛出异常。没有必要使用ExceptionDispatchInfo,并且没有必要将异常存储在本地以便稍后重新抛出。

如果您在出现错误时尝试返回-1,请执行

public async Task<int> Write2Log()
{
  using (var conn = new SqlConnection(connectionString))
  {
    using (var cmd = new SqlCommand(commandText, conn)
    {
      try
      {
        await conn.OpenAsync();
        return await cmd.ExecuteNonQueryAsync();
      }
      catch
      {
        return -1;
      }
    }
  }
}

方法不能抛出异常并同时返回值。你必须选择一个。