我有一个用C#编写的方法,该方法连接到Oracle db,进行工作,然后在最后一部分中调用Dispose()。但是,我收到此错误:
ORA-02399 :超出了最大连接时间,您正在注销
刷新时,出现另一个错误: ORA-01012 :未登录
第三次刷新将加载数据。
项目是:类库.NET Core 2.1
NugetPackage:Oracle.ManagedDataAccess.Core(2.18.3)
这是我的代码
public object GetAllDataByDate(string user, DateTime from,DateTime to, int count=10)
{
if (con.State != ConnectionState.Open)
con.Open();
try
{
return ExtractData(user, from,to, count);
}
catch (Exception ex)
{
return new
{
Error = "Error occured during the extraction of data",
ex.GetType().FullName,
ex.Message,
ex.InnerException
};
}
finally
{
con.Dispose();
}
}
我还需要调用con.Close()吗?还是我错过了代码中的某些内容?谢谢
答案 0 :(得分:2)
您的try catch块包含一个return语句,这将绕开finally块的运行。 重构以尝试使用:Authorize email senders with SPF
using(var con = new DisposableObject()){}
模式,不要在try catch catch块内部返回。
任何实现IDisposable的东西都可以与using block
一起使用(建议在99%的时间内使用,但是总有一些例外情况可以证明规则。
尝试捕获块行为的快速示例:
using System;
public class Program
{
public static void Main()
{
Console.WriteLine(Test());
}
public static string Test()
{
var response = "Hi";
try
{
response = "bye";
return response;
}catch(Exception ex){
response = "fail";
}finally{
response = "finally";
}
return response;
}
}
结果将是“再见”而不是“最终”
答案 1 :(得分:0)
最后我解决了。它与代码无关,但与连接字符串本身有关。
Oracle默认情况下在.NET中启用池化,这会导致超时问题。有关更多详细信息,请参见the documentation。
我只需要在连接字符串中添加Pooling=False;
。
同时,我将con.Dispose();
更改为con.Close();
,因为当我在同一TestMethod中两次调用时,它在UnitTest中失败了(尽管它在调试期间确实起作用)
在编写此响应时,我刚刚发现this answer,因此,如果您需要有关连接池的简单说明,建议阅读该答案。