【问题标题】:C# Synchronizing Threads depending on stringC#根据字符串同步线程
【发布时间】:2012-08-24 19:27:47
【问题描述】:

在我的程序中,我需要处理文件。我的程序可以使用多个线程来处理文件,因此我需要某种锁定,因为每个文件一次不应由多个线程处理。

private object lockObj = new object();

public void processFile(string file)
{
  lock(lockObj)
  {
    //... actuall processing
  }
}

上面的代码一次只能处理一个文件,但是两个线程应该可以同时处理两个不同的文件,但不能处理同一个文件。

我的第一个想法是创建一个字典,其中包含文件的密钥和锁定对象的值。 但我想知道是否也可以锁定字符串文件?对此有什么想法吗?

PS:抱歉找不到更好的标题

【问题讨论】:

标签: c# multithreading thread-synchronization


【解决方案1】:

我的第一个想法是创建一个字典,其中密钥作为文件,值作为锁定对象。但我想知道是否也可以锁定字符串文件?对此有什么想法吗?

如果字符串将在运行时创建,则锁定字符串将不安全。最好制作一个对象字典,并使用它们来锁定。

话虽如此,您应该考虑为此字典使用ConcurrentDictionary<string,object>,因为它可以防止字典本身出现竞争条件(或其他锁定)。通过使用GetOrAdd,您可以安全地获取用于锁定的适当对象。

话虽如此,这里可能适合采用不同的方法。您可以使用ConcurrentQueueBlockingCollection 提供要处理的项目列表,然后让固定数量的线程处理它们。这将首先防止同步问题的发生。

【讨论】:

  • 好的,我已经认为锁定字符串不是一个好主意。谢谢你确认。 ConcurrentDictionary 看起来很有用。
【解决方案2】:

我认为您以错误的方式处理此问题。您可以简单地使用带有BlockingCollection 的生产者-消费者模式。一个线程不断读取文件并将它们放入队列(使用Add),而一堆工作线程不断从队列中取出(使用Take)并处理文件。队列的实现方式保证了两个线程不能检索同一个文件,因此不需要显式锁定。

【讨论】:

  • +1 - 虽然通常使用 BlockingCollection,您会使用 GetConsumingEnumerable() 而不是 Take - 如果您想将其用作队列,您可以直接使用 ConcurrentQueue<T>。 .
  • 好点,但对我不起作用。线程正在做所有类型的工作(不仅仅是文件处理),我不想将文件处理移动到只做这些的线程。
【解决方案3】:

如果您在 c# 中使用线程,您应该自己检查任务并行库 (TPL)。有一个学习曲线,但是一旦掌握了它,您的多线程代码就会变得更简单、更易于维护。

Here's an example 使用 TPL 完全符合您的要求。

【讨论】:

  • 好点,但对我不起作用。线程正在做所有类型的工作(不仅仅是文件处理),我不想将文件处理移动到只做这些的线程。
猜你喜欢
  • 1970-01-01
  • 2011-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-15
  • 2011-12-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多