1

我有下一个控制器

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

尝试以异步方式从数据库中读取数据时,我做错了什么?

4

2 回答 2

2

对 a属性Result的调用Task是一个阻塞调用,并且await将无法发布继续运行。

一旦你已经有了一个任务返回方法,你为什么不直接使用await呢?

public async Task<byte[]> GetImageAsync(int imageId)
{
    var res = await GetImage(imageId);
    if (res != null)
    {
        var wi = new System.Web.Helpers.WebImage(res);
        wi.AddTextWatermark("info");

        return wi.GetBytes();
    }
    return null;
}
于 2013-08-04T21:51:50.913 回答
2

该行的有趣之处在于它调用了可观察SingleAsync对象的 TAP 扩展方法。

我从未使用过将其集合公开为可观察对象的数据存储库,尽管我认为这是可能的。我的第一个猜测是 [返回的任务]SingleAsync没有完成,因为GoodImagesobservable 没有完成。注意SingleAsync必须在看到匹配后继续扫描,以确保它是唯一的匹配;FirstAsync更宽容,一旦看到第一场比赛就会完成。

附带说明一下,我确实建议在服务器上使用awaitResult不是使用。Task.Run所以保罗在这方面的回答很好,尽管在这种情况下Result不会造成僵局。

于 2013-08-05T02:43:22.567 回答