问题描述
.Net Core 3.1多线程控制台应用程序中存在问题;如果对 ThreadPool.QueueUserWorkItem 的调用数超过了在 ThreadPool.SetMaxThreads OracleConnection 将始终为“连接请求超时”引发异常。 / strong>。 “任务”是对Oracle中存储的proc的调用,该过程通过游标返回数据。在单个线程中一切正常,没有问题
.net Core 3.1中使用最新的nuget版本的Oracle.ManagedDataAccess.Client
尝试了Oracle连接字符串,池大小,连接生存时间连接超时等设置的许多组合。似乎没有任何帮助。一旦排队的任务数超过线程数,连接上的 Open 调用将引发异常。
使用OracleConfiguration跟踪会发现以下异常:
2020-09-23 21:30:51.997780 TID:6 (PRI) (ERR) (CP) PoolManager.CreateNewPR() (txnid=n/a) Oracle.ManagedDataAccess.Client.OracleException (0x80004005): Connection request timed out
at OracleInternal.ConnectionPool.PoolManager`3.CreateNewPR(Int32 reqCount,Boolean bForPoolPopulation,ConnectionString csWithDiffOrNewPwd,OracleConnection connRefForCriteria,String instanceName,List`1 switchFailedInstNames)
一些线程处于以下状态“正在搜索空闲连接”:
2020-09-23 21:28:57.443815 TID:13 (PRI) (ENT) (CP) PoolManager.Get() MultiTenant : Searching for a idle connection,retryCountWithoutAffinity: 0
要复制的代码:
using Oracle.ManagedDataAccess.Client;
using Oracle.ManagedDataAccess.Types;
using System;
using System.Data;
using System.Diagnostics;
using System.Threading;
namespace OracleDBStoredProc
{
class Program
{
private static Object lockObj = new Object();
static void Main(string[] args)
{
int numThreads = 10;
ThreadPool.SetMaxThreads(numThreads,numThreads);
for (int i = 0; i < numThreads+ 1; i++)
{
string myMsg = $" TASK {i} ";
ThreadPool.QueueUserWorkItem(CallToDatabase,myMsg);
Console.WriteLine(myMsg + " created.");
}
Console.WriteLine("Finished");
Console.ReadKey();
}
static void CallToDatabase(Object stateInfo)
{
OracleConfiguration.TraceOption = 1;
OracleConfiguration.TraceFileLocation = @"C:\traces";
OracleConfiguration.TraceLevel = 2;
string taskName = (string)stateInfo;
Console.WriteLine(taskName + "started");
string constr = "User Id=MyUser;Password=MyPswd;Data Source=(DESCRIPTION= (ADDRESS= (PROTOCOL=tcp)(HOST=MyServer)(PORT=1521))(CONNECT_DATA= (SERVICE_NAME=myservice)))";
OracleConnection con = new OracleConnection(constr);
con.open();
var cmd = new OracleCommand("MY_APP.GET_MY_DATA",con)
{
CommandType = CommandType.StoredProcedure
};
OracleParameter p1 = cmd.Parameters.Add("refcur_ret",OracleDbType.RefCursor,ParameterDirection.Output);
p1.Direction = ParameterDirection.Output;
cmd.ExecuteNonQuery();
OracleDataReader reader1 = ((OracleRefCursor)p1.Value).GetDataReader();
DataTable test = new DataTable();
test.Load(reader1);
reader1.Close();
reader1.dispose();
p1.dispose();
cmd.dispose();
con.Close();
con.dispose();
String msg = null;
Thread thread = Thread.CurrentThread;
lock (lockObj)
{
msg = String.Format("{0} thread information\t",taskName) +
String.Format(" Thr ID: {0}\t\t",thread.ManagedThreadId);
}
Console.WriteLine(msg);
}
}
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)