c# Azure MVC 检查 Controller 调用.Result 是否存在 blob

标签 c# asp.net-mvc azure model-view-controller azure-blob-storage

我需要检查 MVC Controller 操作中是否存在 blob,并且我尝试以异步方式执行此操作,但没有成功。

如果我同步进行检查,它工作正常并且我得到了期望的结果,代码是下一个:

public ActionResult Index(string id, string size)
{
    string redirectUrl;
    if (string.IsNullOrEmpty(assetBlobUrl)) assetBlobUrl = ConfigurationManager.AppSettings["AssetBlobUrl"];
    if (!string.IsNullOrEmpty(assetBlobUrl))
    {
        bool blobExists = _blobExists(size, id);
        if (blobExists)
        {
            redirectUrl = string.Format(assetBlobUrl, size, id);
            return new PermanentRedirectResult(redirectUrl);
        }
    }

    return ResponseImageNotFound();
}

private bool _blobExists(string size, string assetId)
{
    var container = serviceClient.GetContainerReference("images");
    CloudBlockBlob blockBlob = container.GetBlockBlobReference(size + "/" + assetId + ".jpg");
    bool checkBlobExists = blockBlob.Exists();

    return checkBlobExists;
}

异步(不工作)版本是下一个:

public ActionResult Index(string id, string size)
{
    string redirectUrl;
    if (string.IsNullOrEmpty(assetBlobUrl)) assetBlobUrl = ConfigurationManager.AppSettings["AssetBlobUrl"];
    if (!string.IsNullOrEmpty(assetBlobUrl))
    {
        bool blobExists = _blobExists(size, id).Result;
        if (blobExists)
        {
            redirectUrl = string.Format(assetBlobUrl, size, id);
            return new PermanentRedirectResult(redirectUrl);
        }
    }

    return ResponseImageNotFound();
}

private async Task<bool> _blobExists(string size, string assetId)
{
    bool blobExists = await container.GetBlockBlobReference(size + "/" + assetId + ".jpg").ExistsAsync();

    return blobExists;
}

但这最后一种方式使网络持续加载,并且 ExistsAsync 行永远不会完成,因此永远不会命中下一个返回。

有什么帮助吗?

谢谢。

最佳答案

问题出在调用 .Result ,这通常是一种不好的做法,因为它是可以避免的。

当方法 _blobExists它的await吗? ,它消失,执行任务,然后尝试返回并继续。问题是您之前调用 .Result已阻塞线程,因为它正在等待 _blobExists完成获取 Result 。所以_blobExists wait 正在等待线程空闲,以便它可以继续运行该方法并返回结果。

这意味着您最终会遇到死锁情况,两者都在等待对方。

幸运的是,我们可以将 Controller 操作定义为异步,因此将方法签名更改为:

public async Task<ActionResult> Index(string id, string size)应该修复它。

但是您仍然需要小心,如果您不使用 .NET Core,那么您应该指定您不需要相同的同步上下文,否则问题仍然可能发生,方法是输入 .ConfigureAwait(false)在您的await上线。

关于c# Azure MVC 检查 Controller 调用.Result 是否存在 blob,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55238737/

相关文章:

azure - 辅助角色的本地存储位于文件系统的哪个位置?

c# - 试图避免使用我的泛型进行强制转换

asp.net-mvc - ActionResult 返回调用它的页面

asp.net - Windows Azure - CDN 作为网站?

javascript - 在 JavaScript 条件语句中使用 Razor 语法

c# - 鼠标悬停时显示说明

azure - K8s错误: ImagePullBackOff || read: connection refused

c# - .net core 3.1 WorkerService 不加载配置选项/设置

c# - 在 asp.net mvc 3 中管理每个 session 和请求的 AutoFac 生命周期范围

c# - 在SQL Server中合并一列中的每两行数据