C#中的密集文件I / O和数据处理

时间:2010-01-20 21:41:50

标签: c# multithreading data-processing

我正在编写一个需要处理大型文本文件的应用程序(用几种不同类型的记录进行逗号分隔 - 我没有权力或倾向于更改数据存储格式)。它读入记录(通常是文件中的所有记录,但不总是如此),然后传递每个记录的数据进行一些处理。

现在这部分应用程序是单线程的(读取记录,处理它,读取下一条记录等)我认为在一个线程中读取队列中的记录可能更有效,并且进程它们在小块中的另一个线程中或者当它们可用时。

我不知道如何开始这样的编程,包括必要的数据结构或如何正确实现多线程。任何人都可以提供任何指示,或提供有关如何提高绩效的其他建议吗?

3 个答案:

答案 0 :(得分:3)

如果您可以平衡处理记录的时间与读取记录的时间,可能会获得好处;在这种情况下,您可以使用生产者/消费者设置,例如synchronized queue和工人(或少数)出列和处理。我也可能想要调查并行扩展;写一个IEnumerable<T>版本的阅读代码很容易,之后Parallel.ForEach(或其他Parallel方法之一)应该实际做你想做的一切;例如:

static IEnumerable<Person> ReadPeople(string path) {
    using(var reader = File.OpenText(path)) {
        string line;
        while((line = reader.ReadLine()) != null) {
            string[] parts = line.Split(',');
            yield return new Person(parts[0], int.Parse(parts[1]);
        }
    }
}

答案 1 :(得分:1)

看一下本教程,它包含了你需要的所有内容......这些是微软的教程,包括你所描述的类似案例的代码示例。您的生产者填充队列,而消费者则关闭记录。

Creating, starting, and interacting between threads

Synchronizing two threads: a producer and a consumer

答案 2 :(得分:1)

您还可以查看异步I / O 。在这种风格中,你将从主线程开始一个文件操作,然后它将继续在后台运行,当它完成时,它会调用你指定的回调。在此期间,您可以继续执行其他操作(例如处理数据)。例如,您可以启动异步操作来读取下一个1000字节,然后处理您已有的1000个字节,然后等待下一个千字节。

不幸的是,在C#中编写异步操作有点痛苦。有一个MSDN sample,但它并不好看。使用异步工作流可以在F#中很好地解决这个问题。我写了一篇解释问题的文章,并展示了如何使用C# iterators做类似的事情。

更有价值的C#解决方案是Wintellect PowerThreading库,它使用C#迭代器支持类似的技巧。杰弗里里希特在MSDN Concurrency Affairs中有一篇很好的介绍性文章。