【问题标题】:How to get data from data base with asp mvc 4 async controller and EntityFramework 6 async read from database如何使用asp mvc 4异步控制器和EntityFramework 6异步从数据库读取数据库中的数据
【发布时间】:2013-08-05 10:49:38
【问题描述】:

我有下一个控制器

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

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

【问题讨论】:

  • 有趣的是,同样的问题经常让人们绊倒。每周至少 10 个问题。

标签: asp.net-mvc entity-framework async-await c#-5.0


【解决方案1】:

Task 对属性 Result 的调用是阻塞调用,await 的延续将无法发布以运行。

既然已经有了Task返回方法,为什么不直接使用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;
}

【讨论】:

    【解决方案2】:

    这行的有趣之处在于它调用了SingleAsync,这是observables的TAP扩展方法。

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

    附带说明,我建议在服务器上使用await 而不是Result,而不是使用Task.Run。所以Paulo's answer 在这方面很好,尽管在这种情况下Result 不会 导致死锁。

    【讨论】:

    • 我相信 EF 6 通过像 SingleAsync 这样的扩展支持异步。
    • 单身和第一有不同的意图,没有一个比另一个更好或更有价值。您应该根据自己的意图知道何时使用其中一种。 (msmvps.com/blogs/paulomorgado/archive/2010/03/28/…)。
    猜你喜欢
    • 2015-01-30
    • 2021-03-18
    • 1970-01-01
    • 1970-01-01
    • 2020-09-04
    • 2020-07-14
    • 1970-01-01
    • 2015-01-13
    • 2017-11-25
    相关资源
    最近更新 更多