我有下一个控制器
public async Task<ActionResult> ImageAsync(int id)
{
var img = await _repository.GetImageAsync(id);
if (img != null)
{
return File(img, "image/jpg"); //View(img);
}
byte[] res = new byte[0];
return File(res, "image/jpg");
}
和存储库中的方法
public async Task<byte[]> GetImage(int imageId)
{
try
{
var dbCtx = new smartbags_storeEntities();
var res = await dbCtx.GoodImages.SingleAsync(d => d.ImageId == imageId);
return res != null ? res.ImageData : null;
}
catch (Exception ex)
{
throw ex;
}
}
public async Task<byte[]> GetImageAsync(int imageId)
{
byte[] img = await Task.Run(() =>
{
var res = GetImage(imageId).Result;
if (res != null)
{
var wi = new System.Web.Helpers.WebImage(res);
wi.AddTextWatermark("info");
return wi.GetBytes();
}
return null;
});
return img;
}
但图像阅读的执行在线冻结
var res = await dbCtx.GoodImages.SingleAsync(d => d.ImageId == imageId);
当我尝试以异步样式从数据库中读取数据时,我做错了什么?
答案 0 :(得分:2)
对Result
的{{1}}媒体资源的调用是阻止调用,Task
的延续将无法发布以进行运行。
一旦你有一个任务返回方法,你为什么不只使用await
?
await
答案 1 :(得分:2)
关于该行的有趣之处在于它调用SingleAsync
,这是 observables 的TAP扩展方法。
我从未使用过将其集合公开为可观察对象的数据存储库,但我认为它是可能的。我的第一个猜测是[{1}}返回的任务没有完成,因为SingleAsync
observable没有完成。请注意GoodImages
必须在看到匹配后继续扫描,以确保它是仅匹配; SingleAsync
更宽容,并会在看到第一场比赛后立即完成。
另外,我建议使用FirstAsync
代替await
而不是在服务器上使用Result
。因此Paulo's answer在这方面表现不错,但在这种情况下,Task.Run
不导致死锁。