C#-从一个线程到另一个线程的实时文本供稿

在线程“ A”中,我想读取一个很长的文件,并且发生这种情况,我想将读取的每一行发送到另一个线程“ B”,这将对它们执行某些操作.

基本上,我不想在开始处理行之前等待文件加载完成.
(我绝对想要2个线程并在它们之间进行通信;我以前从未做过此事,我想学习)

那么,我该怎么做呢?
线程A在线程A向线程B发送另一行之前,应等待线程B完成对“当前行”的处理.那么线程B中的缓冲区又如何呢?

另外,请给出一个示例,说明由于没有发现/看到任何有用的示例,因此我必须在此跨线程通信中使用哪些方法.

谢谢.

解决方法:

首先,尚不清楚两个线程在这里是否一定有用.单个线程一次读取一行(使用StreamReader相当容易)并在处理过程中处理每一行可能至少也可以执行.文件读取被缓冲,并且操作系统可以在请求数据的代码之前进行读取,在这种情况下,大多数读取将立即完成,因为下一行已由操作系统预先从磁盘上读取,或者您的两个线程都将必须等待,因为数据不在磁盘上. (让2个线程等待磁盘并没有使事情比1个线程等待更快.)唯一可能的好处是,通过在处理完前一个线程之前进行下一个读取操作,可以避免死时间.但无论如何,操作系统通常都会为您执行此操作.因此,多线程的好处在这里充其量是微不足道的.

但是,由于您说自己是在做学习练习,所以这可能不是问题…

我会使用BlockingCollection< string>作为将数据从一个线程传递到另一个线程的机制. (只要您使用的是.NET 4或更高版本.如果没有,我建议您改用.NET 4,它将大大简化此任务.)您将从文件中读取一行并将其放入来自一个线程的集合:

string nextLine = myFileReader.ReadLine();
myBlockingCollection.Add(nextLine);

然后其他一些线程可以从中检索行:

while (true)
{
    string lineToProcess = myBlockingCollection.Take();
    ProcessLine(lineToProcess);
}

这将使读取线程在文件中的运行速度与磁盘所允许的速度一样快,而处理线程将以任何可能的速率处理数据. Take方法只是坐着等待,如果您的处理线程位于文件读取线程之前.

这样做的一个问题是,如果文件很大并且处理速度很慢,则读取线程可能会领先一步-您的程序可能会尝试从文件中读取千兆字节的数据,而只处理了前几千字节.在处理数据之前没有太多意义读取数据-您实际上只想提前阅读一点.您可以使用BlockingCollection< T>的BoundedCapacity属性来限制内容-如果将其设置为某个数字,则如果集合中已经包含该行数,则对Add的调用将被阻止,并且您的阅读线程不会继续进行,直到处理循环处理其下一行.

将使用双线程技术的程序性能与仅从文件中读取行并在单个线程上循环处理它们的性能进行比较将是很有趣的.您将能够在这里看到多线程方法带来的好处(如果有).

顺便提及,如果您的处理非常占用CPU,则可以使用此主题的变体来具有多个处理线程(并且仍然是单个文件读取线程),因为BlockingCollection< T>非常高兴有无数的消费者都阅读该系列.当然,如果完成文件行的处理顺序很重要,那将不是一个选择,因为尽管您将以正确的顺序开始处理,但是如果您有多个处理线程,则可能有一个线程可能会赶超另一个,导致顺序混乱.

上一篇:两个android应用程序如何相互通信?


下一篇:PHP,javascript,ajax-2位用户之间的通信