c#Azure MVC检查控制器中是否存在blob

时间:2019-03-19 10:26:44

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

我需要检查MVC控制器动作中是否存在斑点,而我正在尝试以异步方式进行操作,但没有成功。

如果我同步执行检查,则可以正常工作,并且可以得到所需的结果,并且代码如下:

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

但是,这是Web继续加载的最后一种方式,与ExistsAsync的连接永远不会结束,因此永远不会产生下一个返回。

有帮助吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

问题出在调用.Result上,这通常是一个坏习惯,因为可以避免。

方法_blobExists执行其await时,它消失了,执行任务,然后尝试返回并继续。问题是您先前对.Result的调用已阻塞线程,因为它正在等待_blobExists完成获取Result的操作。因此_blobExists等待正在等待线程释放,以便它可以继续运行该方法并返回结果。

这意味着您最终将陷入僵局,并且两者都在等待对方。

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

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

但是,仍然需要注意,如果您不使用.NET Core,则应指定不需要相同的同步上下文,否则,可以通过在您的计算机上放置.ConfigureAwait(false)来解决问题await行。