ASP.NET Core MVC: как сохранить результат iprogress
Я пытаюсь реализовать индикатор выполнения «в реальном времени», который отображает ход выполнения асинхронной задачи (загрузка больших двоичных объектов). Задача выполняется в сервисе (библиотеке классов), который сам вызывается веб-контроллером.
Метод обслуживания:
public async Task UploadFileToBlob(MemoryStream stream, string path, HttpContext context)
{
IProgress<StorageProgress> progressHandler = new Progress<StorageProgress>(
progress => context.Session.SetString("UploadBytesTransferred", progress.BytesTransferred.ToString());
CloudBlockBlob blob = GetBlockBlob();
await blob.UploadFromStreamAsync(stream, default(AccessCondition), requestOptions, default(OperationContext), progressHandler, new System.Threading.CancellationToken());
}
Вызов контроллера:
await _blobService.UploadFileToBlob(memoryStream, azureStoragePath, HttpContext);
Позже прогресс должен быть получен другим действием контроллера, как здесь:
[HttpPost]
public ActionResult GetFileUploadProgress()
{
long progress = 0;
var sessionEntry = HttpContext.Session.GetString("UploadBytesTransferredPercent");
if (sessionEntry != null)
progress = Convert.ToInt64(sessionEntry);
return Json(progress);
}
Моя первая попытка, как показано в коде, состояла в том, чтобы сохранить прогресс в переменной сеанса, но это не работает и, вероятно, не рекомендуется. Есть ли лучший и надежный способ следить за ходом выполнения задачи? Или что-то не так с кодом?
1 ответ
В итоге я использовал MemoryCache для хранения хода загрузки (он не блокируется запросом на загрузку). Вероятно, не лучшая практика, но достаточная для моих нужд.
public async Task UploadFileToBlob(MemoryStream stream, string path, IMemoryCache cache)
{
IProgress<StorageProgress> progressHandler = new Progress<StorageProgress>(
progress => cache.Set("UploadBytesTransferred", progress.BytesTransferred)
));
var blob = GetBlockBlob(path);
await blob.UploadFromStreamAsync(stream, default(AccessCondition), requestOptions, default(OperationContext), progressHandler, new System.Threading.CancellationToken());
}