Это проблема, связанная с хранилищем Azure и функциями Azure в Microsoft Azure.
У меня есть контейнер внутри хранилища, а также функция таймера. Идея состоит в том, что всякий раз, когда кто-то помещает zip-файлы (содержащие файлы JSON) в контейнер, функция таймера загружает содержимое в базу данных. Функция таймера постоянно проверяет хранилище, содержит ли оно какие-либо zip-файлы. Причина, по которой я выбираю функцию таймера вместо триггера большого двоичного объекта, заключается в том, что база данных не может обрабатывать слишком много запросов одновременно, если кто-то из контейнеров получит большое количество 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();
}
Ожидаемый результат заключается в том, что каждый файл, загруженный в хранилище, должен быть прочитан и загружен только один раз в базу данных.
Фактическим результатом является то, что иногда (это варьируется много, может быть от 1 до 10-100 файлов) файл читается и загружается дважды.