async / await에서 주 스레드 차단

.net async-await asynchronous c# dapper

문제

내 기본 저장소 클래스를 비동기로 만들려고 노력 중이며 몇 가지 문제가 있습니다. 내 C # 응용 프로그램에서 Dapper ORM을 사용하고 있습니다.

기본 방법

protected async Task<List<T>> Read<T>(CommandDefinition cmd) {
    using(SqlConnection myCon = new SqlConnection(Config.DBConnection)) {
        await myCon.OpenAsync();

        IEnumerable<T> results = await myCon.QueryAsync<T>(cmd);

        List<T> retVal = results.ToList();

        myCon.Close();

        return retVal;
    }
}

호출 방법

public List<Category> GetAllActiveCategories(Guid siteGuid) {
    return base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid).Result;
}

모든 것이 나에게 달려있다. async 키워드로 장식 된 메서드 선언이 있습니다. 비동기 메서드를 기다리고 있습니다.

문제는 스레드 블록 await myCon.OpenAsync();await myCon.OpenAsync(); . 이것은 비동기 및 대기를 사용하는 첫 번째 시도이므로 잘못된 작업을 수행하고 있다고 확신하지만 분명하지는 않습니다. 도와주세요!

수락 된 답변

게시 된 읽기 코드가 좋습니다. 문제는 소비 코드에 있습니다. 그것은으로 교착 상태를 취득하는 것이 일반적 async 전화 할 경우 Wait() 또는 Result 반환에 Task 또는 그 선행 Task 까지 호출 체인이다.

이 경우 항상 그렇듯이 일반적인 조언이 적용됩니다. 비동기 코드를 차단하지 마십시오 . async/await 사용하기 시작하면 전체 호출 체인에서 async/await 를 사용해야합니다.

그래서, 당신의 전화 방법은

public Task<List<Category>> GetAllActiveCategoriesAsync(Guid siteGuid) {
    return base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid);
}

... 또는

public async Task<List<Category>> GetAllActiveCategoriesAsync(Guid siteGuid) {
    List<Category> result = await base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid);

    // Do something.

    return result;
}

인기 답변

범인은 다음과 같습니다.

return base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid).Result;

Kirill이 지적했듯이, .Result .Wait() 또는 .Result 를 작업에 사용할 때마다 동기식으로 차단됩니다. 당신이해야 할 일은 다음과 같습니다.

public Task<List<Category>> GetAllActiveCategories(Guid siteGuid) {
    return base.Read<Category>(SPNAME_GETALLACTIVE, siteGuid);
}

이것은 Task를 메소드의 호출 메소드로 리턴 할 것이고, 계속해서 ... 그것은 비동기적인 "모든 방법"이어야한다.

이 코드의 최상위 소비자가 ASP.NET이면 괜찮습니다. Task<IActionResult> (또는 작업에 래핑 된 적절한 반환 유형)을 반환하면 프레임 워크가 await 을 정렬합니다.

콘솔 애플리케이션을 작성하거나 "비동기로 만들 수 없다"면, .Result 를 차단하거나 메소드를 async void 만들고 await 사용해야합니다. 어느 쪽도 슬프게도 훌륭한 해결책이 아닙니다. Async / await은 스택 전체에서 사용해야한다는 의미에서 꽤 공격적입니다.



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
이 KB는 합법적입니까? 예, 이유를 알아보십시오.