c# Azure MVC 从控制器调用 .Result 检查 blob 是不是存在
Posted
技术标签:
【中文标题】c# Azure MVC 从控制器调用 .Result 检查 blob 是不是存在【英文标题】:c# Azure MVC check if blob exists from controller Calling .Resultc# Azure MVC 从控制器调用 .Result 检查 blob 是否存在 【发布时间】:2019-08-09 20:19:27 【问题描述】:我需要检查 MVC 控制器操作中是否存在 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
通常是个坏主意。你能把你的方法改成public async Task<ActionResult> Index
,然后用await _blobExists...
代替.Result
吗?
你就是那个男人@NibblyPig!现在它可以工作了,非常感谢你,如果你把它写成答案,我会把它标记为正确的。
【参考方案1】:
问题在于调用.Result
,这通常是一种不好的做法,因为它可以避免。
当方法_blobExists
执行它的await
时,它会消失,执行任务,然后尝试返回并继续。问题是您之前对.Result
的调用已阻塞线程,因为它正在等待_blobExists
完成获取Result
。所以_blobExists
await 正在等待线程空闲,以便它可以继续运行该方法并返回您的结果。
这意味着您最终会遇到死锁情况,双方都在等待对方。
幸运的是,我们可以将控制器操作定义为异步,因此将方法签名更改为:
public async Task<ActionResult> Index(string id, string size)
应该修复它。
但是您仍然需要小心,如果您不使用 .NET Core,那么您应该指定您不需要相同的同步上下文,否则问题仍然可能发生,方法是将 .ConfigureAwait(false)
放在您的 @987654330 上@线。
【讨论】:
以上是关于c# Azure MVC 从控制器调用 .Result 检查 blob 是不是存在的主要内容,如果未能解决你的问题,请参考以下文章
使用 C# 以编程方式向 MVC 控制器验证 Azure Ad/OpenId 并获取重定向 uri
C# MVC Web 应用服务连接到 Azure 存储 Blob
从控制器获取结果,但在 MVC5 和 C# 中,ajax 调用获取错误而不是成功
C# MVC 架构,我应该从 MODEL 还是 CONTROLLER 调用存储过程