线程安全哈希集

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 是正确的。来源:我。

问题出在别处。我的猜测是会发生以下顺序:

  1. 已添加工作
  2. 作业完成并删除
  3. 已添加相同的作业 ID。在这里,您期望 Add 到 return false 但删除已经完成。

如果这是真的,您需要维护另一组已完成的作业 ID。