我是多线程的新手,我正在尝试以一种方式创建一个枚举器,因为它已经准备好了,但它会继续在后台处理。
我希望能够使用这样的最终类:
library(dplyr)
library(pander)
data.frame(a = sample(LETTERS, 10),
b = sample(LETTERS, 10)) %>%
slice(n()-5:n()) %>%
pander()
但是我想让它在while循环中继续获取下一个结果。
评论:不能并行处理,因为每个结果都取决于之前的结果。
我想到可能有一个结果的队列,并且有一个线程在获取结果的同时返回队列中的第一个结果,但是我无法使其工作。这是我的尝试,但我不知道该做什么 while (await asyncEnumerator.MoveNextAsync())
{
T result = asyncEnum.Current;
//Do Something
}
:
我更新了代码
MoveNext()
显然,如果有更好的方法,我想知道,我是多线程新手。
答案 0 :(得分:4)
但是我想让它在while循环中继续获取下一个结果。
普通的异步枚举器在这里是错误的解决方案。调查员是一种“拉动”技术;他们只在消费代码请求下一个项目时才做。
从“生产者”和“消费者”的角度考虑您的问题。如果生产者只在消费者请求它时才工作,那么你有一个枚举器场景。在您的情况下,您希望生产者独立生成项目,因此枚举器不适合。
一个选项是reactive extensions; observable表示类似于枚举器的值序列,除了可观察量是一种“推”技术。因此,生产者将价值推向消费者,消费者会对新的价值作出反应(因此称为反应性)。
听起来Rx非常适合你,但确实有很高的学习曲线。
更简单的选项可能是使用更传统的生产者/消费者队列。由于您希望异步使用它,因此您需要一个与异步兼容的生产者/消费者队列。 BufferBlock<T>
为one solution,AsyncProducerConsumerQueue<T>
为my AsyncEx library。
在这两种情况下,你都会开始制作人,然后消费:
var queue = new BufferBlock<T>();
// Kick off producer
var producer = Task.Run(() =>
{
while (...)
{
T value = ...;
queue.Post(value);
}
queue.Complete();
});
// Consumer code
while (await queue.OutputAvailableAsync())
{
var value = await queue.ReceiveAsync();
...
}
最终,您需要await
producer
任务,以便您可以正确检测生产者代码中的任何异常。