gpt4 book ai didi

c# - 来自后台 worker 冲突的查询?

转载 作者:行者123 更新时间:2023-12-03 13:16:34 24 4
gpt4 key购买 nike

如果我使用相同的ConnectionString从多个线程执行查询,是否会有问题?如果两个或多个线程尝试同时发送数据会怎样?

string globalConnectionString = @"some_stringHere!";

//create new backgroundWorker if new logFile is created (txt file).
// ....

private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
// get some data from created logFile
string serialNumber = getSerialNumber(logFile);
string testResult = getTestResult(logFile);

// if server is online, send data
if(serverIsOnline)
{
using(SqlConnection connection = new SqlConnecton(globalConnectionString))
{
SqlCommand someCommand = new SqlCommand("some insert/update command here!", connection);
connection.Open();
Command.ExecuteNonQuery();
connection.Close();
}
}
}

最佳答案

如果正确使用并发连接就可以了
假设正确的理由,并发使用多个连接没有问题。数据库可以处理数千个并发客户端连接。
并行执行相同的慢速查询以使其完成得更快,可能会使其变得更慢,因为每个连接都可能阻塞其他连接。许多数据库已经使查询处理并行化,与粗略的客户端并行性相比,产生的结果要好得多。
如果您想使慢速查询更快,则可以通过调查慢速原因并解决性能问题来获得更好的结果。例如,如果要插入1万行,则使用SqlBulkCopy或BULK INSERT加载行要比执行10K INSERT快,而INSERT最终会相互阻塞以访问同一张表甚至数据页
您可以使用相同的连接来执行异步查询(例如,使用ExecuteNonQueryAsync()ExecuteReaderAsync()等,前提是它们一个接一个地执行。)您不能在同一连接上执行多个并发查询,至少不能不经过一些麻烦而已。
真正的问题
真正的问题是首先使用BackgroundWorker。自2012年引入async/await以来,该类已过时。使用BGW,很难组合多个异步操作。可以通过Progress<T>类获得进度报告,并可以通过CancellationTokenSource进行协作取消。检查Async in 4.5: Enabling Progress and Cancellation in Async APIs以获得详细说明。
您可以仅使用await command.ExecuteNonQueryAsync()替换代码中的BGW调用。您可以创建一个异步方法来执行将数据插入数据库的操作:

private async Task InsertTestData(string serialNumber,string testResult)
{
// if server is online, send data
if(serverIsOnline)
{
using(SqlConnection connection = new SqlConnecton(globalConnectionString))
{
var someCommand = new SqlCommand("some insert/update command here!", connection);
someCommand.Parameters.Add("@serial",SqlDbType.NVarChar,30).Value=serialNumber;
...
connection.Open();
Command.ExecuteNonQueryAsync();
}
}
}
如果检索序列号和测试数据很耗时,则可以使用 Task.Run在后台运行它们:
   string serialNumber = await Task.Run(()=>getSerialNumber(logFile));
string testResult = await Task.Run(()=>getTestResult(logFile));
await InsertTestData(serialNumber,testResult);
您还可以使用像 Dapper这样的库来简化数据库:
private async Task InsertTestData(string serialNumber,string testResult)
{
// if server is online, send data
if(serverIsOnline)
{
using(SqlConnection connection = new SqlConnecton(globalConnectionString))
{
await connection.ExecuteAsync("INSERT .... VALUES(@serial,@test)",
new {serial=serialNumber,test=testResults});
}
}
}
Dapper将生成一个参数化查询,并按名称将查询中的参数与匿名对象中的属性进行匹配。

关于c# - 来自后台 worker 冲突的查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64328828/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com