线程安全哈希集
Thread safe Hash Set
我有几个线程正在处理要处理的作业。为了防止工作选择与另一个工作相同的工作,工作与下面的 class 协调:
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)
returns 为假,则进程将忽略该作业并转到下一个作业。一旦作业完成,它将从列表中删除该作业。
不幸的是,这并不是经常发生的事情,我偶尔会遇到两次处理作业的情况(非常糟糕)。问题可能在代码的其他地方,每个线程决定是否与以下代码擦作业:
var jobs = GetJobs();
foreach (var job in jobs)
{
var tryAdd = CURRENT_FILES.TryAdd(job);
if (tryAdd)
{
ImportFile(job);
}
}
有 Remove(job)
方法,我想看看是否有任何方法可以过早调用,但不太可能,因为作业是在处理后移动到另一个目录的文件。
关于 TryAdd(id)
可能不止一次返回 true 的任何建议?
我是否正确使用了同步锁?
class 是正确的。来源:我。
问题出在别处。我的猜测是会发生以下顺序:
- 已添加工作
- 作业完成并删除
- 已添加相同的作业 ID。在这里,您期望
Add
到 return false 但删除已经完成。
如果这是真的,您需要维护另一组已完成的作业 ID。
我有几个线程正在处理要处理的作业。为了防止工作选择与另一个工作相同的工作,工作与下面的 class 协调:
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)
returns 为假,则进程将忽略该作业并转到下一个作业。一旦作业完成,它将从列表中删除该作业。
不幸的是,这并不是经常发生的事情,我偶尔会遇到两次处理作业的情况(非常糟糕)。问题可能在代码的其他地方,每个线程决定是否与以下代码擦作业:
var jobs = GetJobs();
foreach (var job in jobs)
{
var tryAdd = CURRENT_FILES.TryAdd(job);
if (tryAdd)
{
ImportFile(job);
}
}
有 Remove(job)
方法,我想看看是否有任何方法可以过早调用,但不太可能,因为作业是在处理后移动到另一个目录的文件。
关于 TryAdd(id)
可能不止一次返回 true 的任何建议?
我是否正确使用了同步锁?
class 是正确的。来源:我。
问题出在别处。我的猜测是会发生以下顺序:
- 已添加工作
- 作业完成并删除
- 已添加相同的作业 ID。在这里,您期望
Add
到 return false 但删除已经完成。
如果这是真的,您需要维护另一组已完成的作业 ID。