簡體   English   中英

任務的 C# 控制台應用程序線程問題

[英]C# console application threading issue with Tasks

我有以下代碼片段:

lock (lockObject) 
{
  foreach (KeyValuePair<string, List<string>> entry in productDictionary) 
  {
    string writePath = String.Format(@"{0}\{1}-{2}.txt", directoryPath, hour,entry.Key);
    Task writeFileTask = Task.Factory.StartNew(() => WriteProductFile(writePath, entry.Value));
  }
}

productDictionary 是我試圖迭代的<string, List<string>>ConcurrentDictionary 對於每個鍵值對,我試圖根據Key構建一個文件路徑,然后寫出存儲在Value中的字符串列表。 為此,我啟動了一個調用以下方法的新任務:

public static void WriteProductFile(string filePath, List<string> productQuotes)
{
    using(StreamWriter streamWriter = new StreamWriter(filePath)) 
    {
        productQuotes.ForEach(x => streamWriter.WriteLine(x));
    }
}

單步執行代碼一開始看起來一切正常。 WriteProductFile的方法調用處放置一個斷點表明正確的參數正在通過 Task 傳遞到方法中。 但是,當我的程序實際使用 WriteProductFile 方法時,參數變得不匹配。 即,一個與文件路徑不匹配的字符串列表已被傳入,因此一旦程序完成,我的數據就不好用了。 不會拋出任何錯誤,程序運行良好,但錯誤的信息被寫入錯誤的文件。

我認為 ConcurrentDictionary 和 Lock 會處理可能出現的任何線程問題,但顯然我錯過了一些東西。 有任何想法嗎?

您正在捕獲循環變量。 您必須在循環內部聲明一個局部變量。

foreach (KeyValuePair<string, List<string>> entry in productDictionary) 
{
  string writePath = String.Format(@"{0}\{1}-{2}.txt", directoryPath, hour, entry.Key);
  List<string> list = entry.Value; // must add this.
  Task writeFileTask = Task.Factory.StartNew(() => WriteProductFile(writePath, list));
}

在 C# 5 之前,單個循環變量用於循環的所有迭代。 每個閉包都引用相同的變量,因此在循環的新循環開始時更新該值。 要獲得明確的解釋,您應該閱讀 Eric Lippert 的帖子: 關閉被認為有害的循環變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM