2012-10-12 24 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