工作中,客户将多个XML文件放在FTP服务器上,需要我们自己去获取这些XML文件并存储到数据库中。如果使用单纯的单线程编码,则三天三夜也无法读完客户一天发布的数据,故需要多线程编码来解决。
代码如下:
using System;
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System.Xml;
class Program
{
static async Task Main()
{
string directoryPath = @"C:\Your\Directory\Path"; // 更改为您的目录路径
if (Directory.Exists(directoryPath))
{
const int maxParallelTasks = 10; // 最大并行任务数量
List<Task> tasks = new List<Task>();
foreach (string filePath in Directory.GetFiles(directoryPath, "*.xml"))
{
Task task = Task.Run(async () =>
{
await ReadXmlFileAsync(filePath);
});
tasks.Add(task);
if (tasks.Count >= maxParallelTasks)
{
await Task.WhenAny(tasks);
tasks.RemoveAll(t => t.IsCompleted);
}
}
await Task.WhenAll(tasks);
Console.WriteLine("所有文件已读取完成。可以关闭数据流。");
}
else
{
Console.WriteLine("指定的目录不存在。");
}
Console.ReadLine();
}
static async Task ReadXmlFileAsync(string filePath)
{
try
{
using (FileStream fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
using (XmlReader reader = XmlReader.Create(fileStream))
{
// 在此处异步读取 XML 文件的内容或执行其他操作
Console.WriteLine($"已异步读取文件: {filePath}");
while (await reader.ReadAsync())
{
// 处理 XML 文件内容
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"读取文件时出错: {filePath}. 错误信息: {ex.Message}");
}
}
}
在给定的示例代码中,通过限制最大并行任务数量为10个,尽管有100个XML文件,但代码仅同时处理最多10个文件。这是因为在 foreach
循环中的任务创建部分,会检查当前并行任务数量,并在达到最大并行任务数量时停止创建新的任务,直到某些任务完成并释放了资源。
当遍历文件列表时,会逐个创建任务并添加到 tasks
列表中。如果当前的任务数量达到了 maxParallelTasks
(这里是10),代码会等待任意一个任务完成(使用 Task.WhenAny
),然后移除已完成的任务,以便腾出一个空位来启动新的任务。
所以,即使有100个XML文件,但在整个处理过程中,同时处理的任务数量始终不会超过限制的最大并行任务数量(10个)。在一个任务完成后,将有新的任务加入队列直至所有文件都被处理完成。
因此,该代码能够处理所有100个XML文件,但处理的同时最多只有10个任务在执行。