OracleDataAdapter,Fill 方法挂起,如何处理连接 terminations/drop offs/cut 出局?

OracleDataAdapter, Fill method hangs, how do I handle connection terminations/drop offs/cut outs?

我有一个连接到远程服务器以查询数据的 C# 程序。数据很大,所以查询大约需要 2 分钟才能完成。在这 2 分钟 window 期间,互联网中断了。这导致作业无法完成,程序卡在获取数据例程中。

它建立了连接,但在 select 查询期间它被切断了。将命令超时设置为 30 秒无效。遇到此错误时,我需要查询失败,因为程序可以处理失败但无法处理卡住。谢谢!

更新:包括代码

OracleConnection connection = new OracleConnection(connectionstring);
OracleDataAdapter oracleDataAdapter = new OracleDataAdapter(new OracleCommand(query, connection));
oracleDataAdapter.SelectCommand.CommandTimeout = 30;

  DataSet dataSet = new DataSet();
  try
  {
    oracleDataAdapter.Fill(dataSet, table); //Hangs on this line when connection is lost
    return dataSet;
  }
  catch
  {
    throw;
  }
  finally
  {
    dataSet.Dispose();
    oracleDataAdapter.Dispose();
  }

再次更新:

我需要做的是处理这种情况,因为我不想要悬空进程。

最简单的就是一旦连接丢失,程序就会抛出错误。那就是我不知道该怎么做。我以为 commandtimeout 会修复它,但它没有。

假设您使用的是 ODP.Net,我发现您的陈述有几个问题。请尝试以下操作:

DataSet dataSet = new DataSet();
using (OracleConnection connection = new OracleConnection(connectionstring))
{
  using (OracleDataAdapter oracleDataAdapter = new OracleDataAdapter(new OracleCommand(query, connection)))
  {
    oracleDataAdapter.Fill(dataSet, table);
  }
}
return dataSet;

using 块将处理连接和数据适配器的处理。在您的示例中,连接没有得到处理,这可能是您问题的一部分。此外,如果您打算 return 它,我认为您不想处理数据集。

由于您使用 Throw 冒泡异常,因此我删除了异常处理。请记住,这会使异常冒泡,因此在您的调用代码链中的某个地方,您将需要捕获异常并处理它。如果应用程序只是坐在那里,那么请注意任何空的 "catch" 块吃异常。

有几个重复报告此问题,例如:System being hang when the connection is lost while adapter is filling the datatables

我在 MSDN 上找到了一个很好的线程,OP 回答了这个问题:

I have solved this problem a while back, sorry i forgot to come and let you all know. I worked out that the code stopped executing at that line because (for some reason) there was already an open connection to the database.

Since DA.Fill would open a connection itself if there wasnt one previously opened, it was having a hissy fit and bombing out.

I solved this by putting Connection.Close(); before and after any connection to the database is needed.

基于此我们可以看到您没有明确打开到数据库的连接。建议你做一个:

connection.Open();

同时按照 Steve Py 的回答 using 确认您正在关闭连接并处理非托管资源。

更新后的答案:

        DataSet dataset = new DataSet();

        using (OracleConnection connection = new OracleConnection(connection))
        {
            using (OracleDataAdapter oracleDataAdapter = new OracleDataAdapter(new OracleCommand(query, connection)))
            {
                oracleDataAdapter.SelectCommand.CommandTimeout = 30;
                connection.Open();
                oracleDataAdapter.Fill(dataset, table);
            }
        }

        return dataset;