是什么导致此特定方法陷入僵局? [英] What is causing this particular method to deadlock?

查看:54
本文介绍了是什么导致此特定方法陷入僵局?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽我所能,我一直选择异步.但是,我仍然无法使用不是为异步构建的ASP.NET Membership.结果,我对诸如 string [] GetRolesForUser()之类的方法的调用无法使用异步.

As best as I can, I opt for async all the way down. However, I am still stuck using ASP.NET Membership which isn't built for async. As a result my calls to methods like string[] GetRolesForUser() can't use async.

为了正确地建立角色,我依赖于来自各种来源的数据,因此我正在使用多个任务来并行获取数据:

In order to build roles properly I depend on data from various sources so I am using multiple tasks to fetch the data in parallel:

public override string[] GetRolesForUser(string username) {
   ...
   Task.WaitAll(taskAccounts, taskContracts, taskOtherContracts, taskMoreContracts, taskSomeProduct);
   ...
}

所有这些任务只是使用实体框架从SQL Server数据库中获取数据.但是,最后一个任务( taskSomeProduct )的引入导致死锁,而其他方法都没有.

All of these tasks are simply fetching data from a SQL Server database using the Entity Framework. However, the introduction of that last task (taskSomeProduct) is causing a deadlock while none of the other methods have been.

这是导致死锁的方法:

public async Task<int> SomeProduct(IEnumerable<string> ids) {
    var q = from c in this.context.Contracts

            join p in this.context.Products
            on c.ProductId equals p.Id

            where ids.Contains(c.Id)

            select p.Code;

    //Adding .ConfigureAwait(false) fixes the problem here
    var codes = await q.ToListAsync();
    var slotCount = codes .Sum(p => char.GetNumericValue(p, p.Length - 1));

    return Convert.ToInt32(slotCount);
}

但是,此方法(看起来与所有其他方法非常相似)不会引起死锁:

However, this method (which looks very similar to all the other methods) isn't causing deadlocks:

public async Task<List<CustomAccount>> SomeAccounts(IEnumerable<string> ids) {
    return await this.context.Accounts
        .Where(o => ids.Contains(o.Id))
        .ToListAsync()
        .ToCustomAccountListAsync();
}

我不太确定导致死锁的一种方法的含义.最终,他们俩都在执行查询数据库的相同任务.将 ConfigureAwait(false)添加到一个方法中确实可以解决该问题,但是我不确定是什么将其与其他可以正常执行的方法区分开来.

I'm not quite sure what it is about that one method that is causing the deadlock. Ultimately they are both doing the same task of querying the database. Adding ConfigureAwait(false) to the one method does fix the problem, but I'm not quite sure what differentiates itself from the other methods which execute fine.

修改

为简洁起见,以下是一些我最初省略的代码:

Here is some additional code which I originally omitted for brevity:

public static Task<List<CustomAccount>> ToCustomAccountListAsync(this Task<List<Account>> sqlObjectsTask) {
    var sqlObjects = sqlObjectsTask.Result;
    var customObjects = sqlObjects.Select(o => PopulateCustomAccount(o)).ToList();
    return Task.FromResult<List<CustomAccount>>(customObjects);
}

PopulateCustomAccount 方法仅从数据库 Account 对象返回一个 CustomAccount 对象.

The PopulateCustomAccount method simply returns a CustomAccount object from the database Account object.

推荐答案

ToCustomAccountListAsync 中,您将调用 Task.Result .这是经典的死锁.使用 await .

In ToCustomAccountListAsync you call Task.Result. That's a classic deadlock. Use await.

这篇关于是什么导致此特定方法陷入僵局?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆