我試圖實現的是在集合中的每個值的不同線程中執行一個方法。我想測量所有任務完成前的時間。我的代碼如下:System.Threading.Tasks.Task在循環中執行的奇怪行爲
private ConcurrentQueue<string> Results { get; set; }
public System.Threading.Timer Updater { get; set; }
private Dictionary<int, string> Instances { get; set; }
private void Button_Click(object sender, RoutedEventArgs e)
{
this.Instances = new Dictionary<int, string>();
this.Instances.Add(01, "A");
this.Instances.Add(02, "B");
this.Instances.Add(03, "C");
this.Instances.Add(04, "D");
this.Instances.Add(05, "E");
this.Instances.Add(06, "F");
this.Instances.Add(07, "G");
this.Instances.Add(08, "H");
this.Instances.Add(09, "I");
this.Instances.Add(10, "J");
this.Updater =
new System.Threading.Timer(new TimerCallback(Updater_CallBack), null, 0, 1000);
}
/// <summary>
///
/// </summary>
/// <param name="State"></param>
void Updater_CallBack(object State)
{
this.Operation();
}
private void Operation()
{
var Watcher = new System.Diagnostics.Stopwatch();
Watcher.Restart();
this.Results = new ConcurrentQueue<string>();
var Tasks = new System.Threading.Tasks.Task[this.Instances.Count];
int i = 0;
foreach (var Pair in this.Instances)
{
Tasks[i] = Task.Factory.StartNew(() => { this.Tasker(Pair.Value); });
i++;
}
System.Threading.Tasks.Task.WaitAll(Tasks);
Watcher.Stop();
var Text = new StringBuilder();
foreach (var Result in Results) Text.Append(Result);
System.IO.File.AppendAllText(@"D:\Tasks.TXT", Watcher.ElapsedMilliseconds.ToString() + " " + Text.ToString() + Environment.NewLine);
}
private void Tasker(string Id)
{
switch (Id)
{
case "A": Thread.Sleep(100); this.Results.Enqueue("a"); break;
case "B": Thread.Sleep(100); this.Results.Enqueue("b"); break;
case "C": Thread.Sleep(100); this.Results.Enqueue("c"); break;
case "D": Thread.Sleep(100); this.Results.Enqueue("d"); break;
case "E": Thread.Sleep(100); this.Results.Enqueue("e"); break;
case "F": Thread.Sleep(100); this.Results.Enqueue("f"); break;
case "G": Thread.Sleep(100); this.Results.Enqueue("g"); break;
case "H": Thread.Sleep(100); this.Results.Enqueue("h"); break;
case "I": Thread.Sleep(100); this.Results.Enqueue("i"); break;
case "J": Thread.Sleep(100); this.Results.Enqueue("j"); break;
}
}
我希望這裏是每次不同的結果塔斯克方法10倍的執行,但。當我看看我的結果時,我看到以下內容:
200 jjjjjjjjjj
101 jjjjjjgjjj
101 hhhhhhhhjj
101 hjjjjjjjjj
101 jjjjjjjjhj
100 jjjjjjjjjh
101 jjjjjjjjjj
Tasker方法多次執行'j'。我無法弄清楚爲什麼該方法沒有爲集合中的其他字母執行。我在這裏錯過了什麼?
這是「關閉錯誤」,在這個網站上有很多很多帖子。見[這個問題](http://stackoverflow.com/questions/8898925/is-there-a-reason-for-cs-reuse-of-the-variable-in-a-foreach/8899347) –
我wouldn'噸稱它是一個錯誤。我會用'Tasks = this.Instances.Select(x =>(Action)(()=> this.Tasker(x.Value)))將foreach切換出來,選擇(x => Task.Factory.StartNew X))。ToArray的()'。這就像C#一樣可以編譯和運行的僞代碼。 – Will
@Will這是OP代碼中的一個錯誤,他無意中關閉了正在修改的變量。 – Servy