【发布时间】:2015-09-19 17:14:01
【问题描述】:
我有一个计数器,用来统计当前处理的大报表
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 属性来实现的)。在大报表的情况下,系统然后 Interlock 递增处理的大报表 int 并处理大报表。处理完大型报表后,系统联锁会递减该值。
整个想法是我一次只允许处理一个报告,因此一旦一个线程正在处理一个大报告,其他线程应该无法访问数据库中的一个大报告。 bool allowLargeReport 变量检查handledLargeReports int 和是否超过限制。
我很好奇这是否是正确的实现,因为我无法在星期一之前对其进行测试。我不确定我是否必须使用 InterLocked 类或只是将 processesLargeReports 变量定义为 volatile 成员。
【问题讨论】:
-
您可能需要
lock而不是增量。作为一项学术练习,请参阅 Eric Lippert 在How Locking Works in C# 上的文章,以更深入地讨论它的一般作用。 -
@theB 的链接不再有效。原始博客可以在 ericlippert.com/2014/02/12/how-does-a-lock-work 找到,但主要只是指向同一原始站点的断开链接。
标签: c# .net multithreading locking