gpt4 book ai didi

C# - 从一个线程到另一个线程的实时文本馈送

转载 作者:行者123 更新时间:2023-11-30 15:46:24 28 4
gpt4 key购买 nike

在线程“A”中,我想读取一个很长的文件,碰巧,我想将读取的每个新行发送到另一个线程“B”,这会对它们做一些事情。

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

那么,我该怎么做呢?线程 A 应该等待线程 B 完成“当前行”的处理,然后线程 A 才能将另一行发送给线程 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如果您的处理线程领先于文件读取线程,方法只是坐下来等待。

其中的一个问题是,如果文件很大并且您的处理速度很慢,您的读取线程可能会超前 - 您的程序可能会尝试从文件中读取 GB 的数据,而同时只处理了前几千字节。在处理数据之前读取数据没有多大意义 - 你真的只想提前阅读一点。你可以使用 BlockingCollection<T>BoundedCapacity属性来限制事物 - 如果你将它设置为某个数字,那么调用 Add如果集合中已经有那么多行,将会阻塞,并且您的读取线程将不会继续,直到处理循环处理它的下一行。

将使用双线程技术的程序的性能与仅从文件中读取行并在单线程循环中处理它们的程序的性能进行比较会很有趣。您可以在此处查看多线程方法的好处(如果有的话)。

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

关于C# - 从一个线程到另一个线程的实时文本馈送,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4326720/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com