c# - 如何在没有进程锁定的情况下一次处理一堆文件
问题描述
我有以下每 30 秒运行一次的代码。通过 C# 计时器,
var sourceFiles = Directory.GetFiles(sourcePath, "*.zip").Select(f => new FileInfo(f));
foreach (var sourceFile in sourceFiles)
{
var success = await ProcessFileAsync(sourceFile);
}
有时在sourcePath
路径中我有大量文件,看起来它在 30 秒内没有完成,其他计时器开始了。因此,我经常收到文件正在使用错误,
该进程无法访问文件“D:\path\file1.Zip”,因为它正被另一个进程使用。
如何处理?请建议。
- 每 30 秒。我一次可以处理 1 个文件,但由于文件数量很大,它会减慢处理速度。
- 我不知道在 1 个文件过程中消耗了多少时间。
解决方案
我使用的一种常见模式是标记正在处理的文件,这样其他进程就不会尝试接触它们——如果您计划并行处理,这也很有用。
var sourceFiles = Directory.GetFiles("*.zip");
foreach (var sourceFile in sourceFiles)
{
var tempFilename = sourceFile + ".processing";
try
{
if (File.Exists(sourceFile))
{
File.Move(sourceFile, tempFilename);
var success = await ProcessFileAsync(sourceFile);
if (success)
{
File.Move(tempFilename, sourceFile + ".done");
}
else
{
File.Move(tempFilename, sourceFile);
}
}
}
catch
{
// Rename the file back to be attempted later.
File.Move(tempFilename, sourceFile);
}
}
推荐阅读
- c# - 没有可用的 MediaTypeFormatter - Web API
- r - 从许多分组的线性回归中对新数据进行评分
- redis - Redis 4 systemd Sentinel 配置文件不可写
- android - 为 Android 构建的 C++ 库使用错误的依赖符号
- css - 如何获取testcafe中标签的css属性?
- amazon-web-services - 为什么eks集群在CloudWatch中没有对应的日志
- java - 停止音频插孔成为媒体记录器上的默认音频源
- elasticsearch - [custom_score] 中 START_OBJECT 的未知键
- google-apps-script - 如何从 Google 表单中的 MultipleChoiceItem 获取图像?
- sql - 在 BigQuery 中将数组大小限制为 1MB