我想創建一個排隊任務運行的方法,所以我試圖用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