Async =>避免死锁并编写执行速度慢的异步代码

时间:2015-09-24 06:38:40

标签: c# asp.net asynchronous async-await

我有这个类有两个公共异步方法,它们也调用一些非同步的私有方法。

这是班级:

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 ....          
}

我也使用这种方法,例如

var obj = await GetSchoolAggreagtedInfo(21).ConfigureAwait(false);

我觉得我有太多的async方法,我担心这些方法可能会造成更多的伤害而不是好的。

有没有更好的方法来完成所有这些异步内容(可能是模式),或者代码是否正常?

0 个答案:

没有答案