我一直在使用HTTP與客戶端進行通信的自定義多線程服務器。要創建新的線程,我一直在使用Task.Factory.StartNew()方法。爲了同步,我一直在使用ManualResetEvent對象。ManualResetEvent和任務問題
下面的代碼的本質:
namespace ThreadTest {
class Program {
private readonly ManualResetEvent _event = new ManualResetEvent(false);
public void Start() {
for (int i = 0; i < 100; i++) {
int num = i;
Task.Factory.StartNew(() => {
Console.WriteLine("Task {0} Started", num);
_event.WaitOne();
});
}
}
static void Main(string[] args) {
var test = new Program();
test.Start();
Console.ReadLine();
}
}
}
在實際的代碼中,_event
對象最終會叫上Set
釋放等待任務。
我遇到的問題是,這段代碼在我的開發機器上運行正常(這是雙內核,每個內核有2個線程並使用MS .NET 4運行時),但不能在我的服務器上運行是單內核,每個內核有1個線程並使用Mono 2.8運行時)。我的機器上輸出是:
Task 0 Started
Task 1 Started
Task 3 Started
Task 2 Started
Task 4 Started
Task 5 Started
...
雖然服務器輸出
Task 53 Started
我的問題是:什麼是我誤解有關ManualResetEvent的或任務?爲什麼TaskFactory會繼續在雙核上執行任務,而不是在單核上執行任務?
更新:
我只是想在我的雙核心(每核心1個線程)的Mac筆記本電腦和我的輸出
Task 97 Started
Task 1 Started
然後什麼都沒有。我也在Mono上用我的開發機器(4線程)嘗試過它,並得到:
Task 99 Started
Task 2 Started
Task 98 Started
Task 0 Started
所以它看起來像一個單聲道的錯誤。
一個問題是您對所有任務使用相同的事件。一旦任何單個任務設置了事件,所有其他等待都將立即落空。雖然這並不能解釋爲什麼你的服務器只顯示一個單一的任務開始。 – 2011-02-13 21:16:50
@Jim Mischel:是的,在真實的代碼中,我有單獨的事件。我只是不明白爲什麼,在單線程機器上,我只能在一次啓動1個任務。 – cdmckay 2011-02-13 21:21:35