我想创建一个排队任务运行的方法,所以我试图用BlockingCollection
来实现它。我发现的问题是每当我尝试添加Task
时,任务都会执行。示例代码如下:使用BlockingCollection排队任务
private void button1_Click(object sender, EventArgs e)
{
textBox2.Clear();
for (int i = 0; i < 10; i++)
_processCollection.Add(BigTask(i));
}
static BlockingCollection<Task> _processCollection = new BlockingCollection<Task>();
Thread ConsumerThread = new Thread(LaunchConsumer);
private static async void LaunchConsumer()
{
while (true)
{
var processTask = _processCollection.Take();
await Task.Run(() => processTask);
}
}
async Task BigTask(int i)
{
await Task.Delay(5000);
textBox2.AppendText($"Text{i}\n");
}
在调试中似乎发生的一切是,所有任务看起来都是在它们被添加到阻塞集合中时运行的。我试图切换阻塞集合使用Action
,但这只是导致什么都没有发生。如下图(只显示变化):
private void button1_Click(object sender, EventArgs e)
{
textBox2.Clear();
for (int i = 0; i < 10; i++)
{
int iC = i;
_processCollection.Add(async() => await BigTask(iC));
}
}
static BlockingCollection<Action> _processCollection = new BlockingCollection<Action>();
Thread ConsumerThread = new Thread(LaunchConsumer);
private static async void LaunchConsumer()
{
while (true)
{
var processTask = _processCollection.Take();
await Task.Run(processTask);
}
}
我觉得我在某处做了一些小的错误,因为它觉得这应该工作。我试图找人做类似的事情,但没有运气,这让我觉得也许我的观念有缺陷,所以随时提出一个替代方案。
嗨,你能澄清一下你的意思吗?使用'Func'。我曾尝试在阻塞收集中使用它,结果没有任何变化。当使用'Action'时,语法仍然和我的相同。 –
关于看不到的结果,我原来的代码示例没有UI的东西,所以我有理由相信它没有执行。无论如何,我在这个例子中都会调用,但仍然没有显示结果。 –
在这种情况下,您可以将'Action'更改为'Func'而无需做任何其他更改。 'async()=> {}'可以转换为'async void'委托或者'async Task'委托,并且编译器会根据调用者的期望来决定。我会尝试修改我的答案,以显示我稍后可以测试的内容。 –
hvd