我有几个线程正在处理作业。为了防止工作与另一个工作相同,工作与下面的课程协调:
public class CurrentlyProcessingCollection
{
private readonly HashSet<string> _currentlyProcessing = new HashSet<string>();
private readonly object _myLock = new object();
public bool TryAdd(string id)
{
return SynchronisedContext(
() =>
{
return _currentlyProcessing.Add(id)
});
}
public void Remove(string id)
{
SynchronisedContext(() => _currentlyProcessingFiles.Remove(id));
}
private T SynchronisedContext<T>(Func<T> function)
{
lock (_myLock)
{
return function();
}
}
}
如果TryAdd(id)
返回false,则进程将忽略该作业并转到下一个作业。一旦完成一项工作,它将从列表中删除该工作。
不幸的是,这不是一直发生的事情,我偶尔会处理两次处理(非常糟糕)。问题可能在代码的其他地方,每个线程决定是否使用以下代码擦除作业:
var jobs = GetJobs();
foreach (var job in jobs)
{
var tryAdd = CURRENT_FILES.TryAdd(job);
if (tryAdd)
{
ImportFile(job);
}
}
有Remove(job)
方法,我正在寻找是否有任何可以过早调用的方法,但这不太可能,因为这些作业是在处理后被移动到另一个目录的文件。
有关TryAdd(id)
如何多次返回true的任何建议?
我是否正确使用同步锁?
答案 0 :(得分:1)
班级是正确的。来源:我。
问题出在其他地方。我的猜测是发生以下序列:
Add
返回false,但删除已经完成。如果确实如此,则需要维护另一个包含已完成作业ID的设置。