首页 > 解决方案 > ASP.NET Core MVC:如何存储 iprogress 结果

问题描述

我正在尝试实现一个显示异步任务(blob 上传)进度的“实时”进度条。该任务在(类库的)服务中执行,该服务本身由 Web 控制器调用。

服务方式:

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);
}

如代码所示,我的第一次尝试是将进度存储在会话变量中,但它不起作用,可能不推荐使用。有没有更好更可靠的方法来获取任务的进度?还是代码有问题?

标签: asp.net-coreasynchronousiprogress

解决方案


我最终使用 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());
}

推荐阅读