2012-02-02 3 views
6

에는 System.Data.SqlClient.SqlCommand 메소드 System.Data.IDbCommand 및 비동기 실행?

BeginExecuteNonQuery 
BeginExecuteReader 
BeginExecuteXmlReader 

비동기 실행
EndExecuteNonQuery 
EndExecuteReader 
EndExecuteXmlReader 

있다.

System.Data.IDbCommand 은 동기 동작만을위한

ExecuteNonQuery 
ExecuteReader 
ExecuteXmlReader 

있다.

비동기 작업을위한 인터페이스가 있습니까?
또한 BeginExecuteScalar가없는 이유는 무엇입니까?

답변

1

IDbCommand가 시작/종료 비동기 방법이 없습니다 1.1 ADO 릴리스.그리고 비동기 메소드가 added in .NET 2.0 인 경우 IDbCommand에 추가하는 것이 큰 변화 였을 것입니다 (인터페이스에 멤버를 추가하는 것은 해당 인터페이스의 구현 자에게 중요한 변경 사항입니다).

BeginExecuteScalar이 존재하지 않는 이유를 모르겠지만 BeginExecuteReader을 감싸는 확장 메서드로 구현할 수 있습니다. 어쨌든 .NET 4.5에서 우리는 이제 사용하기가 더 쉬운 ExecuteScalarAsync을 가지고 있습니다.

+0

'IDbCommand.ExecuteScalarAsync()'가 보이지 않습니다. 어떤 [documentation] (https://msdn.microsoft.com/en-us/library/system.data.idbcommand (v = vs.110) .aspx)를보고 있습니까? – binki

+3

오, 당신은 ['SqlCommand.ExecuteScalarAsync()'] (https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand.executescalarasync%28v=vs.110%29. aspx). 내가 참조. – binki

+1

@binki 또는 ['DbCommand.ExecuteScalarAsync()'] (https://msdn.microsoft.com/en-us/library/hh223677(v=vs.110) .aspx) 인터페이스에 있지만 일부 다형성을 지원합니다. – phoog

-5

없음 그들을 위해 인터페이스가되지 않습니다

당신은 아마 매우 빠른해야 다시 하나 개의 값을 얻기 위해 비동기 호출이 필요하지 않습니다 때문에 BeginExecuteScalar이없는 이유는

+7

그 "하나의 가치"는 50 개의 테이블, 몇 개의 견해, 어쩌면 일부 저장된 procs 등을 포함 할 것입니다. 그것은 대부분 이유가 아닐 것입니다 :) – Onkelborg

+0

그것은 내가 내 자신에게 줄 수있는 유일한 이유이며, 나는 그것이 꽤 있다고 생각합니다. resealable .. 당신의 데이터베이스에서 하나의 값을 얻으려면 50 개의 테이블을 포함해야하는데 스키마에 문제가 있고 비동기 호출이 도움이되지 않습니다 :-) –

+0

@Massimiliano Peluso : 당신이 옳은 경우의 95 %에서 부여됩니다. 그러나 그러한 스키마가 있다면 짧은 시간에 변경하는 방법이 없기 때문에 비동기 메서드의 필요성이 높아집니다. –

0

당신을 사용자 정의 코드로 비동기 동작을 구현할 수 있습니다. 사용자의 질문과 마찬가지로 복잡하지 않기 때문에 - 목표에 대한 표준 비동기 작업이 없습니다.

3

실제로 BeginExecuteNonQuery, EndExecuteNonQuery 등과 같은 비동기 동작을 만드는 것은 다소 어려운 작업입니다. 이러한 API의 구현은 별도의 스레드를 생성하고 데이터베이스 응답을 기다리고 콜백을 호출하는 것보다 훨씬 뛰어납니다. 그들은 I/O 오버랩에 의존하고 훨씬 더 나은 스레드 경제를 제공합니다. 네트워크 홉, 명령의 데이터베이스 처리 기간 동안 추가 스레드가 소비되지는 않습니다. 이는 전체 통화 시간의 99 % 일 것입니다. 몇 가지 호출에서는 아무런 차이가 없지만 높은 처리량 서버를 설계 할 때 스레드 경제가 매우 중요하게됩니다.

왜 내가 BeginExecuteScalar가 없는지 궁금 해서요. 또한 예를 들어 ODP.Net을 비롯한 대부분의 다른 공급자에는 비동기 API가 전혀 없습니다!

그렇습니다. 비동기 작업을위한 인터페이스가 없습니다.

1

"한 값"을 검색하는 경우에도 대부분의 경우 1) 데이터베이스 서버로의 네트워크 홉, 2) 데이터베이스 서버 실행 명령에 소요됩니다. 데이터 세트에 1000 개의 레코드를 읽는 데 소비하는 것보다 훨씬 더 많은 시간이 소요됩니다. 따라서 BeginExecuteScalar가없는 이유는 분명하지 않습니다.

2

정확하게이 문제를 해결하기 위해 IDBConnection.IDbCommand/IDataReader에 존재하는 경우 비동기 메서드를 호출하거나 " 티.

출처 : https://github.com/ttrider/IDbConnection-Async

NuGet : https://www.nuget.org/packages/IDbConnection-Async/

예 : 그들은 아직 원래 .NET에 존재하지 않았기 때문에

 using (IDbConnection connection = new SqlConnection(connectionString)) 
     { 
      await connection.OpenAsync(); 

      IDbCommand command = connection.CreateCommand(); 
      command.CommandText = "SELECT Name FROM Person;"; 
      using (IDataReader reader = await command.ExecuteReaderAsync()) 
      { 
       do 
       { 
        while (await reader.ReadAsync()) 
        { 
         if (!await reader.IsDBNullAsync(0)) 
         { 
          var name = reader.GetFieldValueAsync<string>(0); 
          Assert.IsNotNull(name); 
         } 
        } 
       } while (await reader.NextResultAsync()); 
      } 
     } 
1

DbCommand 및 그 친구들을 데이터베이스 API를 사용할 때 인터페이스 인 것처럼 처리 할 것을 권장합니다. 다양한 데이터베이스 제공 업체를 통해 API를 일반화하기 위해 또는 가능 Task*Async()과 같은 최신 기술이 포함되어 있기 때문에 또는 그 이상의 것이 좋습니다.

MS는 새로운 기능이있는 새로운 방법을 IDbCommand에 추가 할 수 없습니다. 사용자가 IDbCommand에 메소드를 추가하려는 경우 누구나 코드에 해당 인터페이스를 자유롭게 구현할 수 있으므로 MS는 ABI 및 API 호환성을 프레임 워크에 보존하는 데 많은 노력을 기울이기 때문에 큰 변화입니다. .net의 릴리스에서 인터페이스를 확장하면 이전에 작동했던 고객 코드가 컴파일을 중단하고 다시 컴파일되지 않는 기존 어셈블리가 런타임 오류가 발생하기 시작합니다. 덧붙여, 그들은 에 뒤에서 못생긴 캐스팅을하지 않고 확장 메서드를 통해 적절한 *Async() 또는 Begin*() 메서드를 추가 할 수 없습니다. 이는 유형 안전성을 파괴하고 불필요하게 동적 런타임 캐스팅을 도입하는 나쁜 연습입니다.

한편 MS는 ABI를 위반하지 않고 DbCommand에 새로운 가상 메소드를 추가 할 수 있습니다. DbCommand을 상속 받았고 같은 이름의 멤버가 추가 된 경우 기본 클래스에 새 메소드를 추가하는 것이 API를 깨뜨리는 것으로 간주 될 수 있습니다 (컴파일 타임, 런타임과 같이 깨지기 쉽지 않음). CS0108: 'member1' hides inherited member 'member2'. Use the new keyword if hiding was intended. 경고를 받기 시작합니다. . 따라서 DbCommand은 우수 사례를 따르는 코드 소비에 미치는 영향을 최소화하면서 새로운 기능을 얻을 수 있습니다 (예 : myCommand.GetType().GetMethods()[3].Invoke(myCommand, …)과 같은 것을 사용하여 시스템이 유형 시스템과 작동하지 않는 한 대부분의 기능이 계속 작동합니다).

MS가 인터페이스를 좋아하는 사람들을 지원하는 데 사용할 수 있었던 전략은 IAsyncDbCommand과 같은 이름의 새로운 인터페이스를 도입하고 DbCommand을 구현하는 것이 었습니다. 그들은 이것을하지 않았습니다. 이유를 모르지만 복잡성을 증가시키고 직접 소비하는 대신 DbCommand의 대안은 단점이있는 소비 인터페이스에 대부분의 이점을 제공합니다. 즉, 거의 돌아 가지 않으면 일할 수 있습니다.