gpt4 book ai didi

c# - 在 .NET 中使用 Interlocked 类进行多线程处理的正确方法

转载 作者:行者123 更新时间:2023-11-30 14:52:02 25 4
gpt4 key购买 nike

我有一个计数器,统计当前处理的大报表

private int processedLargeReports;

我正在生成并启动五个线程,其中每个线程都访问此方法:

public bool GenerateReport(EstimatedReportSize reportSize)
{
var currentDateTime = DateTimeFactory.Instance.DateTimeNow;
bool allowLargeReports = (this.processedLargeReports < Settings.Default.LargeReportLimit);
var reportOrderNextInQueue = this.ReportOrderLogic.GetNextReportOrderAndLock(
currentDateTime.AddHours(
this.timeoutValueInHoursBeforeReleaseLock),
reportSize,
CorrelationIdForPickingReport,
allowLargeReports);

if (reportOrderNextInQueue.IsProcessing)
{
Interlocked.Increment(ref this.processedLargeReports);
}

var currentReport = this.GetReportToBeWorked(reportOrderNextInQueue);

var works = this.WorkTheReport(reportOrderNextInQueue, currentReport, currentDateTime);
if (reportOrderNextInQueue.IsProcessing)
{
Interlocked.Decrement(ref this.processedLargeReports);
}
return works;
}

“reportOrderNextInQueue”变量从数据库获取报告顺序并检查报告顺序是“正常”还是“大”(这是通过定义 reportOrderNextInQueue 变量的 bool IsProcessing 属性实现的)。如果是大型报告,系统随后会互锁递增 processedLargeReport int 并处理大型报告。处理大型报告后,系统联锁会递减该值。

整个想法是我一次只允许处理一个报表,所以一旦一个线程正在处理一个大报表,其他线程就不能访问数据库中的一个大报表。 bool allowLargeReport 变量检查 processedLargeReports int 和是否超出限制。

我很好奇这是否是正确的实现方式,因为我无法在星期一之前对其进行测试。我不确定我是必须使用 InterLocked 类还是只将 processedLargeReports 变量定义为 volatile 成员。

最佳答案

假设您有 5 个线程开始运行上面的代码,并且 LargeReportLimit 为 1。它们将全部读取 processedLargeReports 为 0,allowLargeReports 对它们而言将为真,并且它们将同时开始处理 5 个项目,尽管您的限制为 1。所以如果我理解正确的话,我真的看不出这段代码是如何实现你的目标的。

稍微扩展一下:您读取 processedLargeReports 然后操作(使用它来检查您是否应该允许处理报告)。你表现得好像这个变量不能在阅读和行动之间改变,但事实并非如此。在您读取变量和对变量执行操作之间,任何数量的线程都可以使用 processedLargeReports 做任何事情,因为您没有锁定。在这种情况下互锁只会确保 processedLargeReports 在所有线程处理完所有任务后始终为 0,仅此而已。

如果您需要限制对某些资源的并发访问 - 只需为此使用适当的工具:Semaphore 或 SemaphoreSlim 类。创建允许 LargeReportLimit 线程进入的信号量。在处理报告之前,等待您的信号量。如果达到并发线程处理报告的数量,这将阻塞。处理完成后,释放信号量以允许等待线程进入。这里不需要使用 Interlocked 类。

关于c# - 在 .NET 中使用 Interlocked 类进行多线程处理的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32671042/

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