【问题标题】:Thread safe Hash Set线程安全哈希集
【发布时间】:2015-09-14 18:11:58
【问题描述】:

我有几个线程负责处理要处理的工作。为防止工作与另一个工作接替相同的工作,这些工作与以下类协调:

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 有什么建议吗?

我是否正确使用了同步锁?

【问题讨论】:

  • 您需要提供更多代码,错误不在此处
  • 我还建议您删除 SynchronisedContext 方法,它不会增加任何价值,只会使您的代码膨胀。只需 lock (_mylock) {...}。

标签: .net multithreading asynchronous synchronization mutex


【解决方案1】:

类是正确的。来源:我。

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

  1. 已添加工作
  2. 工作完成并被移除
  3. 添加了相同的作业 ID。在这里,您希望 Add 返回 false,但删除已经完成。

如果是这样,您需要维护另一个包含已完成作业 ID 的集合。

【讨论】:

  • 我认为你是对的。感谢您检查CurrentlyProcessingCollection
猜你喜欢
  • 2014-05-05
  • 2011-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-18
  • 2016-09-07
  • 1970-01-01
  • 2012-05-02
相关资源
最近更新 更多