为什么Task.WaitAll不等待我的所有任务完成?C#
在我开始之前。我看过类似的问题,但我认为在我的情况下,这些问题没有答案 我对Task.Factory.StartNew和Task.WaitAll有问题 我在任务中初始化的已创建类中的对象上获得null异常,即使引发null异常的代码应该等待所有任务完成 如果我在没有任务的情况下运行这段代码,它可以正常工作 为什么Task.WaitAll不等待所有任务完成为什么Task.WaitAll不等待我的所有任务完成?C#,c#,multithreading,asynchronous,C#,Multithreading,Asynchronous,在我开始之前。我看过类似的问题,但我认为在我的情况下,这些问题没有答案 我对Task.Factory.StartNew和Task.WaitAll有问题 我在任务中初始化的已创建类中的对象上获得null异常,即使引发null异常的代码应该等待所有任务完成 如果我在没有任务的情况下运行这段代码,它可以正常工作 为什么Task.WaitAll不等待所有任务完成 Queue<Task> tasks = new Queue<Task>(); //Go
Queue<Task> tasks = new Queue<Task>();
//Go through all transactions in the file via the reader.
foreach (transaction t in xr.read_x12(_progressbar_all_processing)) {
tasks.Enqueue(Task.Factory.StartNew(() => {
//Create a new provider from the current transaction and then
//add it to the global provider list.
provider p = new provider(t);
t_info.provider_list.Add(p);
//Null out the segments of the current transaction
//We are done with them and now the garbage collector
//can clean them up for us.
t.segments = null;
}));
}
Task.WaitAll(tasks.ToArray());
foreach(provider p in t_info.providers){
//Every provider has a List<claims> claims_list
//Do something with p.claims_list
foreach(claim c in p.claims_list){ //<--null exception here
}
}
Queue tasks=new Queue();
//通过读卡器查看文件中的所有事务。
foreach(xr.read_x12(\u progressbar\u all\u processing)中的事务t){
tasks.Enqueue(Task.Factory.StartNew(()=>{
//从当前事务创建新的提供程序,然后
//将其添加到全局提供程序列表中。
提供商p=新提供商(t);
t_info.provider_list.Add(p);
//清空当前事务的段
//我们已经完成了它们,现在是垃圾收集器
//我可以帮我们清理一下。
t、 段=空;
}));
}
Task.WaitAll(tasks.ToArray());
foreach(t_信息提供者中的提供者p){
//每个提供者都有一个索赔清单
//用p.U清单做点什么
foreach(p.claims_list中的claim c){/t_info.provider_list
是一个列表
这个类不能同时让多个线程写入,必须同步对该列表的访问
lock(t_info.provider_list)
{
t_info.provider_list.Add(p);
}
这将只允许一个线程一次执行Add调用,并将修复集合损坏的问题。一个更容易纠正的建议:使用Task。而不是使用。使每个任务返回一个值,该值是其自身工作单元的结果
当所有
都有签名时:
Task<TResult[]> WhenAll<TResult>(IEnumerable<Task<TResult>> tasks)
Task whalll(IEnumerable任务)
因此,您将一组任务传递给它,每个任务的计算结果都是TResult
,然后返回一个任务,该任务的计算结果是一个数组,其中包含完成后的所有结果
通过这种方式,您可以免除使用线程安全集合在任务之间传递数据的任何责任。出错的可能性要大得多
它还与async
/await
兼容,后者都是关于使用通过任务返回的值。您永远不应该使用StartNew
(这不是您的问题,但您应该注意)。对于您的实际问题,t\u info.provider\u list
的类型是什么?@ScottChamberlain-谢谢,我会记住这一点。它是list,provider有一个list。所有这些都是在provider中生成的constructor@Quantic如果任务出现故障task.WaitAll
将抛出一个agragateException
谢谢Scott,这似乎是错误的o已经解决了我的问题。以后我会尽量更加小心我的线程。