System.ArgumentException: An item with the same key has already been added. Key: database=timsdb;server=127.0.0.1;port=3306;user id=admin;password=123456;characterset=utf8;allowuservariables=True;defaultcommandtimeout=600;sslmode=Disabled
at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
at MySql.Data.MySqlClient.MySqlPoolManager.GetPool(MySqlConnectionStringBuilder settings)
at MySql.Data.MySqlClient.MySqlConnection.Open()
数据库版本:Mysql Ver 8.0.30 for Win64 on x86_64 (MySQL Community Server - GPL)
mysql.data.dll 引用版本 8.0.31
var providerName="MySql.Data.MySqlClient";
var _connectionString="database=timsdb;server=127.0.0.1;port=3306;user id=admin;password=123456;characterset=utf8;allowuservariables=True;defaultcommandtimeout=600;sslmode=Disabled";
DbProviderFactory _dbProviderFactory = DbProviderFactories.GetFactory(providerName);
Database _database = new Database(_connectionString, _dbProviderFactory);
DbConnection _dbConnection = _dbProviderFactory.CreateConnection();
_dbConnection.ConnectionString = _connectionString;
while(true)
{
if (_dbConnection == null || IsDisposed)
{
_dbTransaction = null;
_dbConnection = _dbProviderFactory.CreateConnection();
_dbConnection.ConnectionString = _connectionString;
}
if (_dbConnection.State == ConnectionState.Open)
{
continue;
}
_dbConnection.Open();
}
1、连接过多导致?报错不一致
2、连接关闭过于频繁?
这个错误消息表明,你已经在字典中添加了与键 database=timsdb;server=127.0.0.1;port=3306;user id=admin;password=123456;characterset=utf8;allo 相同的项,并且该键值对已存在。在 MySql.Data.MySqlClient.MySqlPoolManager.GetPool 函数中,你需要确保连接字符串是唯一的。你可以尝试给字符串添加一个随机数,以保证连接字符串的唯一性,如下所示:
var connectionString = "database=timsdb;server=127.0.0.1;port=3306;user id=admin;password=123456;characterset=utf8;allowuservariables=True;defaultcommandtimeout=600;sslmode=Disabled;" + Guid.NewGuid().ToString();
这可能是因为一个具有相同键的项目已经被添加。请检查您的代码,看看是否有重复添加重复key的情况。
你如果看源码就会发现实际上是因为MySqlPoolManager.GetPool会复用连接,调用了 Pools.Add(text, value);这是一个静态的Dictionary<string, MySqlPool>变量,但Pools本身并非线程安全的,在当前连接未初始化时,多线程情况下,就会引发这个异常。
private static readonly Dictionary<string, MySqlPool> Pools;
static MySqlPoolManager()
{
Pools = new Dictionary<string, MySqlPool>();
ClearingPools = new List<MySqlPool>();
maxConnectionIdleTime = 180;
timer = new Timer(new TimerCallback(CleanIdleConnections), null, maxConnectionIdleTime * 1000 + 8000, maxConnectionIdleTime * 1000);
AppDomain.CurrentDomain.ProcessExit += new EventHandler(UnloadAppDomain);
AppDomain.CurrentDomain.DomainUnload += new EventHandler(UnloadAppDomain);
AssemblyLoadContext.GetLoadContext(Assembly.GetExecutingAssembly())!.Unloading += new Action<AssemblyLoadContext>(UnloadAssemblyLoadContext);
}
public static async Task<MySqlPool> GetPoolAsync(MySqlConnectionStringBuilder settings, bool execAsync, CancellationToken cancellationToken)
{
string text = GetKey(settings);
SemaphoreSlim semaphoreSlim = new SemaphoreSlim(1);
semaphoreSlim.Wait(CancellationToken.None);
Pools.TryGetValue(text, out var value);
if (value == null)
{
value = await MySqlPool.CreateMySqlPoolAsync(settings, execAsync, cancellationToken).ConfigureAwait(continueOnCapturedContext: false);
Pools.Add(text, value);
}
else
{
value.Settings = settings;
}
semaphoreSlim.Release();
return value;
}
请问你解决了吗