C# 异步=>;避免死锁和编写执行缓慢的异步代码

C# 异步=>;避免死锁和编写执行缓慢的异步代码,c#,asp.net,asynchronous,async-await,C#,Asp.net,Asynchronous,Async Await,这个类有两个公共异步方法,它们还调用一些异步的私有方法 这是课程: public class AggregatedDataService { public async Task<OrganizationAggregatedInfo> GetOrganizationAggregatedInfo(int organizationId) { var organization = await GetOrganization(organizationId); var organ

这个类有两个公共异步方法,它们还调用一些异步的私有方法

这是课程:

public class AggregatedDataService
{
public async Task<OrganizationAggregatedInfo> GetOrganizationAggregatedInfo(int organizationId)
{
    var organization = await GetOrganization(organizationId);
    var organizationContact = await GetOrganizationContact(organization.ID);
    var associations = await GetOrganizationAssociations(organization.ID);

    //await Task.WhenAll(organizationContact, associations);
    return new OrganizationAggregatedInfo(organization.Name, organization.Address, organizationContact,
        associations);
}

public async Task<SchoolAggregatedInfo> GetSchoolAggreagtedInfo(int schoolId)
{
    if(schoolId < 1)
        return null;

    var school = await GetSchool(schoolId);
    if (school == null)
    {
        return null;
    }
    var getSchoolAddressTask = GetSchoolAddress(schoolId); 
    var getMemberSchoolsTask = GetMemberSchools(schoolId);
    var getSchoolCurriculumTask = GetSchoolCurriculum(schoolId);
    var getSchoolFacilitiesTask = GetSchoolFacilities(schoolId);
    var getSchoolAssociationsTask = GetSchoolAssociations(schoolId);
    var getSchoolAcreditationsTask = GetSchoolAcreditations(schoolId);
    var getGovernanceStructureTask = GetGovernanceStructure(schoolId);

    await Task.WhenAll(getSchoolAddressTask, getMemberSchoolsTask, getSchoolCurriculumTask,
            getSchoolFacilitiesTask, getSchoolAssociationsTask, getSchoolAcreditationsTask,
            getGovernanceStructureTask);

    var schoolAddress = getSchoolAddressTask.Result;
    var memberSchools = getMemberSchoolsTask.Result; 
    var teacherInfo = await GetTeacherInformation(schoolAddress.SchoolID);
    var curriculum = getSchoolCurriculumTask.Result;
    var facilities = getSchoolFacilitiesTask.Result;
    var associations = getSchoolAssociationsTask.Result;
    var accreditations = getSchoolAcreditationsTask.Result;
    var studentInfo = await GetStudentInformation(schoolAddress.SchoolID);
    var governanceStructure = getGovernanceStructureTask.Result; 

    SchoolContactReadView contact = null;

    if (schoolAddress != null)//TODO: consider using null propagation
    {
        if (schoolAddress.SchoolContact != null)
            contact = SchoolContactReadView.ShowSchoolContactView(schoolAddress.SchoolContact);
    }

    var schoolAggregateInfo = new SchoolAggregatedInfo
    {
        Name = school.Name,
        Address = school.Address,
        MemberSchoolsCount = memberSchools.Count(),
        GovernanceStructure = governanceStructure,
        Accreditations = accreditations.ToList(),
        Associations = associations.ToList(),
        Contact = contact,
        Curriculum = curriculum,
        Facilities = facilities.ToList()
    };

    return schoolAggregateInfo;
}

private async Task<List<OrganizationAssociationReadView>> GetOrganizationAssociations(int organizationId)
{
    HttpResponseMessage response = await client.GetAsync("api/organization/associations/" + organizationId);
    if (response.StatusCode == HttpStatusCode.OK)
    {
        var contentResult = await response.Content.ReadAsAsync<List<OrganizationAssociation>>();
        associations = contentResult.Select(OrganizationAssociationReadView.MapFrom).ToList();
    }
    else
    {
        _log.Error("API Error Reason: " + response.ReasonPhrase);
    }
}

private async Task<OrganizationContactReadView> GetOrganizationContact(int organizationId)
{
    HttpResponseMessage response = await client.GetAsync("api/organization/contact/" + organizationId);
    if (response.StatusCode == HttpStatusCode.OK)
    {
        var contentResult = await response.Content.ReadAsAsync<OrganizationContact>();
        var organizationContactReadView = OrganizationContactReadView.MapFrom(contentResult);

        organizationContact = organizationContactReadView;
    }
    else
    {
        _log.Error("API Error Reason: " + response.ReasonPhrase);
    }
}

private async Task<OrganizationReadView> GetOrganization(int organizationId)
{
    same as the other other methods....
}

private async Task<GovernanceStructureReadView> GetGovernanceStructure(int schoolId)
{
    ....
}

private async Task<IEnumerable<AccreditationReadView>>  GetSchoolAcreditations(int schoolId)
{
    ....
}

.... all other method ....          
}
我觉得我有太多的
async
方法,我担心这些方法可能弊大于利


有没有更好的方法来完成所有这些异步工作(可能是一种模式),或者代码可以吗?

“每个等待都会衍生出新的线程(从我对异步和等待的理解来看)。”——这不是真的。原则上,异步方法将在某些现有线程上运行,但这取决于您的上下文。你在UI线程上吗?异步回调通常也会在UI线程上运行。您是否在控制台应用程序/web服务器中?回调通常会在线程池线程上运行(但不会为每个任务创建一个新的线程)。Eric Lippert的文章是一篇很好的文章——“异步方法的全部要点是尽可能多地停留在当前线程上”我不确定你在问什么——async/await是否完全未经测试,case错误和死锁——这真的不太可能;一个人能调用这样的代码并导致死锁吗;代码看起来合理吗?是的(但CodeReview可能更适合网站)。第二个问题根本无法回答,因为您没有定义“更好”的标准……感谢@Damien_,不相信文章有助于消除误解的人。如果您能证明程序在正常参数范围内运行时没有问题,这将非常适合我们(我不完全确定死锁在什么时候变成“正常参数内的问题”,YMMV)以及是否包含省略的代码。如果不这样做,它将在CR上分别作为中断代码或示例代码关闭
var obj = await GetSchoolAggreagtedInfo(21).ConfigureAwait(false);