3

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

private object lockObj = new object();

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

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

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

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

4

3 回答 3

4

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

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

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

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

于 2012-08-24T19:30:27.593 回答
2

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

于 2012-08-24T19:31:33.213 回答
0

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

这是一个使用 TPL 完全符合您要求的示例。

于 2012-08-24T19:37:35.390 回答