线程安全哈希集

时间:2015-09-14 18:11:59

标签: .net multithreading asynchronous synchronization mutex

我有几个线程正在处理作业。为了防止工作与另一个工作相同,工作与下面的课程协调:

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的任何建议?

我是否正确使用同步锁?

1 个答案:

答案 0 :(得分:1)

班级是正确的。来源:我。

问题出在其他地方。我的猜测是发生以下序列:

  1. 添加了工作
  2. 已完成工作
  3. 添加了同样的工作ID。在这里,您希望Add返回false,但删除已经完成。
  4. 如果确实如此,则需要维护另一个包含已完成作业ID的设置。