[英]Task.ContinueWith not working how I expected
請考慮以下代碼。 我開始執行一個什么都不做的任務,然后使用ContinueWith()開始對一個遞增計數器的方法進行10次調用。
當我運行該程序時,它打印“0”,表示還沒有調用increment()方法。 我期待它被調用10次,因為那是我調用ContinueWith()的次數。
如果我取消注釋“Thread.Sleep(20)”行,則按預期打印“10”。
這在發布或調試模式下發生。 我的系統是運行Windows 7 x64的超級線程(8個邏輯核心)的核心2 quad。
我假設我對Task.ContinueWith()如何工作有一些基本的誤解....
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication4
{
class Program
{
static void Main()
{
using (var task = Task.Factory.StartNew(()=>{}))
{
for (int i = 0; i < 10; ++i)
{
task.ContinueWith(_=> increment());
// Thread.Sleep(20); // Uncomment to print 10 instead of 0.
}
task.Wait();
}
// This prints 0 UNLESS you uncomment the sleep above.
Console.WriteLine(counter);
}
static void increment()
{
Interlocked.Increment(ref counter);
}
private static int counter;
}
}
任何人都可以了解這里發生的事情嗎?
原因很簡單:您等待已經完成的任務。 你真正想要的是等待你在循環中創建的十個任務:
var tasks = new List<Task>();
for (int i = 0; i < 10; ++i)
{
tasks.Add(task.ContinueWith(_=> increment()));
}
Task.WaitAll(tasks.ToArray());
當然。 您在初始任務完成時打印出值 - 您不是在等待繼續發生。 換句話說,當初始任務完成時,會發生11件事:
如果您願意,可以將所有這些鏈接在一起:
task = task.ContinueWith(_=> increment());
然后,當原始任務完成時,將觸發一個增量器。 當完成后,接下來的增量將閃光。 什么時候結束[...]。 當最終的增量器結束時,您的Wait
呼叫將返回。
如果您更改主體如下:
using (var task = Task.Factory.StartNew(() => { }))
{
var t = task;
for (int i = 0; i < 10; ++i)
{
t = t.ContinueWith(_ => increment());
// Thread.Sleep(20); // Uncomment to print 10 instead of 0.
}
t.Wait();
}
你會得到10
沒有睡覺。 主要的變化是t = t.ContinueWith(...)
和t
是必要的,因為你不允許改變using()
變量。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.