这是有关Microsoft Azure中Azure存储和Azure功能的问题。
我在存储设备中有一个容器以及计时器功能。这个想法是,只要有人将zip文件(包含JSON文件)放入容器中,计时器函数就会将内容上传到数据库中。计时器功能会连续检查存储是否包含任何zip文件。我选择使用计时器函数而不是Blob触发器的原因是,如果容器中有人收到大量zip文件,数据库将无法同时处理太多查询。
现在,问题是,有时函数会将同一文件两次上载到数据库,即使在上载后删除存储中的文件也是如此。我不知道为什么,因为在我看来,每次测试都已成功删除文件。
到目前为止,我已经测试了从控制台应用程序上载本地文件的操作,该程序运行正常,因此上载本身没有任何问题。 我已经测试了运行方法之后,然后将所有压缩文件上传到存储设备。这也很好。 当计时器功能正在运行并读取zip文件,而更多的zip文件被添加到存储中时,似乎会出现此问题。
计时器功能:
static ConcurrentQueue<CloudBlockBlob> queue;
[FunctionName("RezippedUploadFunction")]
public static async System.Threading.Tasks.Task RunAsync([TimerTrigger("0 * * * * *")]TimerInfo myTimer, ILogger log)
{
var storage = new Storage();
var blobs = await storage.GetCloudBlockBlobsAsync("rezipped");
if (blobs.Count == 0) return;
queue = new ConcurrentQueue<CloudBlockBlob>(blobs);
var ctasks = 30;
var tasks = new Task[ctasks];
for (var i = 0; i < ctasks; i++)
{
tasks[i] = Task.Factory.StartNew(() => UploadTaskTest());
}
Task.WaitAll(tasks);
blobs.ForEach(x => Task.WaitAll(storage.HardDeleteBlobAsync(x.Name, "rezipped")));
Thread.Sleep(1000 * 60);
log.LogInformation($"C# Timer trigger function executed at: {DateTime.Now}");
}
上传方法:
static void UploadTaskTest()
{
var finish = DateTime.Now.AddMinutes(5);
var zip = new Zip();
var storage = new Storage();
CloudBlockBlob blob;
while (queue.TryDequeue(out blob))
{
var stream = storage.DownloadBlobAsync(blob.Name, "rezipped");
Task.WaitAll(stream);
zip.UploadZip(stream.Result);
//if (DateTime.Now > finish) break;
}
}
其他方法:
public async Task HardDeleteBlobAsync(string name, string container)
{
await GetContainer(container).GetBlockBlobReference(name).DeleteAsync();
}
预期结果是,每个上载到存储的文件只应读取一次并上载到数据库。 实际结果是,有时(这在10-100个文件中有很大差异)在读取和上传文件两次之后。
答案 0 :(得分:0)
我认为已经触发了多个实例,而不是单个实例。但是我不是100%确信
或者,您可以使用事件网格来触发Azure函数。由于事件将仅包含上下文,因此可以帮助您确定是否处理文件,或者忽略文件是否较大。此解决方案将是最佳选择,还可以降低运行该功能的成本(您可以切换到使用量而不是应用服务计划)。