我们有一个应用程序,该应用程序从S3中提取数据并写入数据库。在该应用程序中,我们正在打开用于并发/并行的线程,其中每个线程都从特定的S3密钥中提取。
原始应用程序代码是在.Net Framework 4.6.1中编写的,我们将代码库迁移到.Net core 3.0。这是一个简单的过渡。
下面是Parallel.ForEach的代码段,用于提取数据和处理:
Parallel.ForEach(PotentialFiles.Rows.OfType<DataRow>(), (row) =>
{
if (ProcessFile(row[1].ToString(), Date, 15))
{
LastFileID = Math.Max(LastFileID, Convert.ToInt32(row[0]));
FirstFileID = Math.Min(FirstFileID, Convert.ToInt32(row[0]));
}
});
我们遇到了聚合异常:
System.AggregateException:发生一个或多个错误。 (发生一个或多个错误。(任务被取消。))
ProcessFile
方法包括来自AWSSDK.S3的S3获取对象,这是异步方法。
但是同一段代码可以在Windows上完美运行。
我们可以使用Partitioner解决该问题:
var tasks = System.Collections.Concurrent.Partitioner.Create(PotentialFiles.AsEnumerable())
.GetPartitions(10)
.Select(partition => Task.Run(() =>
{
using (partition)
{
while (partition.MoveNext())
{
var row = partition.Current;
if (ProcessFile(row[1].ToString(), Date, 15))
{
LastFileID = Math.Max(LastFileID, Convert.ToInt32(row[0]));
FirstFileID = Math.Min(FirstFileID, Convert.ToInt32(row[0]));
}
}
}
})).ToArray();
await Task.WhenAll(tasks);
使用上面的代码,它可以在Linux实例上运行。
如果.Net Core是跨平台的,那么为什么同一段代码不能在不同的平台(Windows和Linux)上运行。不同平台上的Task Scheduler是否存在问题? 我在这里想念什么?