2012-10-12 56 views
1

這似乎是由於我的IEnumerable狀態不一致而導致線程錯誤。具體來說,List<T>如何在多個線程中使用列表<T>?

這是我的工作流程:

List<string> IDs = getIDs(); 
RunTask(IDs); 
RunTask(IDs); 

public void RunTask(List<string> IDs) 
{ 
    TaskScheduler scheduler = new TaskScheduler(); 
    TaskFactory factory = new TaskFactory(scheduler); 
    var tasks = IDs.Select(name => factory.StartNew(() => action(name))).ToArray(); 
    Task.WaitAll(tasks); 
} 

我對我的WaitAll()呼叫得到一個一般性錯誤。

我的想法是,我得到某種不同步的IEnumerator,並且我需要通過Array.CopyTo()複製我的List,然後將它傳遞給我的多個線程。

這是我的例外:

Error: One or more errors occurred. 
One or more errors occurred. 
at System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout, CancellationToken cancellationToken) 
at System.Threading.Tasks.Task.WaitAll(Task[] tasks, Int32 millisecondsTimeout) 
at System.Threading.Tasks.Task.WaitAll(Task[] tasks) 

在這個問題上有什麼想法?

+0

你有沒有考慮過使用類似互斥體的東西來阻止多個線程同時訪問列表? – Corey

+0

你不這樣做,這是不安全的。查看這個問題的答案以獲得一些很好的信息。 http://stackoverflow.com/questions/6601611/no-concurrentlistt-in-net-4-0編輯 - 我沒有注意到你沒有寫入列表。多個閱讀器都很好。 – asawyer

+0

不幸的是,我需要兩個線程來訪問列表中的數據。 – Codeman

回答

7

我不認爲這是一個線程錯誤 - 只要每個任務不修改IDs列表,它應該是安全的。如果任何等待的任務拋出異常或被取消,則Task.WaitAll()將拋出AggregateException

您可以訪問異常的InnerExceptions以查看錯誤是什麼。

try 
{ 
    Task.WaitAll(tasks); 
} 
catch(AggregateException ex) 
{ 
    foreach(Exception in ex.InnerExceptions) { ... } 
} 
+0

我最終做了一件非常類似於這件事,它通過給我整個堆棧跟蹤 - 事實證明,我的服務沒有正確的文件權限。請將您的標記標記爲正確,謝謝! – Codeman