【发布时间】:2020-01-13 21:02:13
【问题描述】:
我需要使用批处理概念异步处理输入文件中的每条记录。示例 - 假设我的输入文件有 100 条记录,并且我的批量大小设置为 10,我需要分 10 批处理记录(每批 10 条记录),并且所有这些批次都应该异步处理。批量大小 10 不是固定的,可能会有所不同。
我有一个读取函数,它从文件中读取每条记录,如果读取了 10 条记录,我需要调用一个异步方法来处理这些记录 使用任务。但是实际的线程应该继续读取下一组记录并填充下一组记录(读取接下来的 10 条记录),一旦它们被读取,调用相同的异步方法来使用另一个任务处理这些记录,这应该一直持续到所有记录都被阅读。
现在,我可以读取记录并填写批次,然后逐个处理每个批次,但我想异步执行。
我在下面提供了我的代码的 sn-p:
public async Task ProcessRecordAsync(InputFile)
{
public int recordCount = 0;
List<Task> TaskList = new List<Task>();
While (condition to check if records present)
{
Object getRecordVal = ReadInputRecord();
if(++recordCount >= 10)
{
var LastTask = new Task(async () => await ProcessRecordAsync());
LastTask.Start();
TaskList.Add(LastTask);
}
}
Task.WaitAll(TaskList.ToArray());
}
ProcessRecordAsync() --> This is the function which processes the input record
我认为我在错误地调用任务时出错了。一旦批次被填充,我想使用任务调用 ProcessRecordAsync 函数,主线程仍应继续读取记录并填充下一组批次。使用此代码,我遇到了异常。
我遇到以下错误:
System.InvalidOperationException:集合已修改;枚举操作可能无法执行。 在 System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource 资源) 在 System.Collections.Generic.List`1.Enumerator.MoveNextRare()
这是处理多项任务的正确方法吗?
【问题讨论】:
-
错误消息表明您正在迭代一个列表,但在迭代期间修改了该列表。从您发布的代码中看不到可能发生这种情况的地方。
-
您可以考虑将 MoreLinq 包的 .Batch 扩展方法用于批处理方面。 nuget.org/packages/MoreLinq
-
您可能需要考虑 TPL DataFlow。它允许分工和流水线,但比单独使用
async/await和Task更容易 -
非常感谢您的帮助。我认为问题中发布的问题已得到解决。我认为我在迭代时错误地更改了列表,这导致了问题。我现在面临一个新问题并正在努力解决这个问题。如果我不能解决,我会开一个新帖子并给出详细的解释。
标签: c# multithreading asynchronous async-await task