Dapper의 취소 토큰

.net async-await c# cancellation-token dapper

문제

저는 Nuget의 Dapper 1.31을 사용하고 있습니다. 나는이 아주 간단한 코드 스 니펫을 가지고 있는데,

string connString = "";
string query = "";
int val = 0;
CancellationTokenSource tokenSource = new CancellationTokenSource();
using (IDbConnection conn = new SqlConnection(connString))
{
    conn.Open();
    val = (await conn.QueryAsync<int>(query, tokenSource.Token)).FirstOrDefault();
}

QueryAsync 에서 F12 키 를 누르면

public static Task<IEnumerable<T>> QueryAsync<T>
     (
        this IDbConnection cnn, 
        string sql, 
        dynamic param = null, 
        IDbTransaction transaction = null, 
        int? commandTimeout = null, 
        CommandType? commandType = null
     );

서명에 CancellationToken 이 없습니다.

질문 :

  • 전체 솔루션에 컴파일러 오류가 없다고 가정 하고 스 니펫을 완벽하게 빌드 수있는 이유는 무엇입니까?
  • 필자는 장기 실행 SQL 쿼리를 생성하는 방법을 tokenSource.Cancel() 호출하면 실제로 메소드를 취소 할 수 있는지 테스트 할 수 없으므로 필자를 용서하십시오. .Cancel() 실제로 메서드를 취소하고 OperationCancelledException throw합니까?

고맙습니다!

수락 된 답변

취소 토큰을 매개 변수 개체로 전달하고 있습니다. 그건 효과가 없을거야.

dapper의 첫 번째 비동기 메소드는 취소 토큰을 노출하지 않았습니다. 선택적인 매개 변수 (별도의 오버로드로 기존 어셈블리를 손상시키지 않기 위해)로 추가하려고하면 "모호한 메서드"컴파일 문제로 인해 혼란스러워집니다 . 따라서 별도의 API를 통해이를 노출해야했습니다. CommandDefinition 입력하십시오.

val = (await conn.QueryAsync<int>(
    new CommandDefinition(query, cancellationToken: tokenSource.Token)
).FirstOrDefault();

그런 다음 체인을 따라 취소 토큰을 모든 예상 장소로 전달합니다. ADO.NET 공급자가 실제로 그것을 사용하는 것은 일이지만, 그것은 대부분의 경우에 효과가있는 것으로 보인다. 작업이 진행중인 경우 OperationCancelledException 대신 SqlException 이 발생할 수 있습니다. 이것은 다시 ADO.NET 공급자에게 달려 있지만 많은 의미가 있습니다. 중요한 것을 중단시킬 수 있습니다. 그것은 중요한 연결 문제로 나타납니다.

질문에 관해서 :

전체 솔루션에 컴파일러 오류가 없다고 가정하고 스 니펫을 완벽하게 빌드 할 수있는 이유는 무엇입니까?

왜냐하면 ... 그것은 당신이 기대하는 것을하지 않더라도 유효한 C #입니다.

필자는 장기 실행 SQL 쿼리를 생성하는 방법을 모르므로 tokenSource.Cancel ()을 호출하면 실제로 메소드를 취소 할 수 있는지 테스트 할 수 없으므로 필자를 용서하십시오. .Cancel ()이 실제로 메서드를 취소하고 OperationCancelledException을 throw합니까?

ADO.NET 공급자 - 특정,하지만 예 일반적으로 작동합니다. "장기 실행 SQL 쿼리를 생성하는 방법"의 예로서; SQL 서버의 waitfor delay 명령은 여기에서 다소 유용하며 통합 테스트에서 사용하는 것입니다.


인기 답변

다음 줄을 추가하여 Dapper lib의 SqlMapper.cs 를 수정할 수 있습니다.

    internal IDbCommand SetupCommand(IDbConnection cnn, Action<IDbCommand, object> paramReader)
    {
        var cmd = cnn.CreateCommand();

#if ASYNC
        // We will cancel our IDbCommand
        CancellationToken.Register(() => cmd.Cancel());
#endif

자신의 Dapper 라이브러리를 다시 빌드하고 즐기십시오 :)



아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow
아래 라이선스: CC-BY-SA with attribution
와 제휴하지 않음 Stack Overflow