我有一个 Azure 应用服务 (Windows),正在其上开发一个连续的、队列触发的 Web 作业。此 Web 作业从 Azure 存储帐户文件共享检索文件,并尝试将内容复制到给定位置。如果该文件已存在,则会被覆盖。否则,将创建一个新文件。
为了下载文件,我执行以下操作:
ShareFileClient file = shareDir.GetFileClient($"{list}.dat");
if (!file.Exists())
{
logger.LogError($"ERROR: Couldn't find {list}.dat file in the file share.");
return;
}
try
{
ShareFileDownloadInfo download = file.Download();
using (FileStream fs = new FileStream(Path.Combine(downloadPath, $"{list}.dat"), FileMode.Create, FileAccess.ReadWrite, FileShare.None))
{
download.Content.CopyTo(fs);
}
}
catch (Exception ex)
{
logger.LogError($"EXCEPTION: An exception occurred while downloading {list}.dat.{Environment.NewLine}{ex.Message}{Environment.NewLine}{ex.InnerException?.Message ?? ""}");
return;
}
以应用服务文件系统中尚不存在该文件的情况为例。尽管使用上面代码中的语句在队列触发函数中创建了文件,但我收到以下异常:
该进程无法访问文件“PATH TO LIST FILE”,因为它正在被另一个进程使用。
我不确定它是否相关,但有问题的文件大小约为 1.5 GB。我检查了应用程序服务计划,它在内存和 CPU 方面远未达到极限,因此我非常有信心这不是问题所在。似乎文件锁定在某个时候被撤销,但我不明白是什么原因造成的。还应该注意的是,这些是 Microsoft 提供的用于从存储帐户文件共享下载文件的说明,如下所示:
这原来是与消息租约到期相关的问题,导致队列消息被重新处理。以下代码将消息租约延长 2 小时(完成工作的任意时间),并防止消息被过快地重新处理:
QueueClient copyFilesQueueClient = new(Environment.GetEnvironmentVariable("AzureWebJobsStorage"), $"{siteName}-copy-list-files");
copyFilesQueueClient.UpdateMessage(queueMessage.MessageId, queueMessage.PopReceipt, queueMessage.Body, new TimeSpan(2, 0, 0));