2

작업을 사용하고 모든 결과가 반환되기를 기다리면서 같은 매개 변수를 사용하여 여러 저장 프로 시저를 비동기 적으로 호출 할 수 있는지 궁금합니다. 나는 세 가지 질문이TPL 작업 및 저장 프로 시저

private void SetReportVariables(string reportName, string[] storedProcedureName, string _clientGroup, string _clientCode, string _finYear, string _period) 
    { 
     Task[] tasks = new Task[storedProcedureName.Length]; 

     for (int i = 0; i < storedProcedureName.Length; i++) 
     { 
      List<Pair> parameters = new List<Pair>(); 
      parameters.Add(new Pair("@ClientGroup", _clientGroup)); 
      parameters.Add(new Pair("@ClientCode", _clientCode)); 
      parameters.Add(new Pair("@FinYear", _finYear)); 

      tasks[i] = DataBaseCall(storedProcedureName[i], parameters.ToArray()); 
     } 
     Task.WaitAll(tasks); 

     ...........Do something with the DataTables......... 
    } 

: 나는 콜

private Task<DataTable> DataBaseCall(string procedureName, params Pair[] where) 
    { 
     DataTable data = new DataTable(); 
     SqlConnection connection = new SqlConnection(connStr); 

     SqlCommand command = new SqlCommand(procedureName, connection); 
     connection.Open(); 

     for (int i = 0; i < where.Length; i++) 
     { 
      command.Parameters.Add(where[i].First.ToString(), where[i].Second.ToString()); 
     } 

     var readerTask = Task<SqlDataReader>.Factory.FromAsync(command.BeginExecuteReader, command.EndExecuteReader, null); 
     return readerTask.ContinueWith(t => 
      { 
       var reader = t.Result; 
       try 
       { 
        reader.Read(); 
        data.Load(reader); 
        return data; 
       } 
       finally 
       { 
        reader.Dispose(); 
        command.Connection.Close(); 
        command.Connection.Dispose(); 
        command.Dispose(); 
       } 
      }); 
    } 

:

나는 다음 있습니다.

  1. 이렇게하는 것이 좋은 방법이 있습니까?
  2. 어떤 아이디어로 인해 _ _ _ _ _ _ _ _ _ _ _ _ _ _ 변수가 생략되어 오류가 발생하는 경우가 있습니다.
  3. 작업에서 데이터 테이블을 반환 할 수 있습니까?

감사

마이크이 방법 근본적으로 아무 문제가 없다

답변

0
  1. .
  2. 코드에서 _finYear의 출처를 표시하지 않지만 표시되는 코드를 기반으로 sproc에 올바르게 전달되지 않는 이유는 표시되지 않습니다.
  3. 물론 DataTable을 반환 할 수 있습니다. 여러 스레드에서 동시에 액세스하는 것은 안전하지 않지만 스레드간에 문제없이 전달할 수 있습니다.

코드에 사소한 버그는 당신이해야한다는 또 다른 시도/마침내 Begin/EndExecuteReader에 비동기 호출에 문제가 있다면 t.Result는 예외가 발생하고, 그 것 것이 가능하기 때문에 로직을 처리하여 계속에서 명령과 연결을 처분하지 마십시오. 그러면 더 좋을 것입니다 :

readerTask.ContinueWith(t =>    
{     
    try 
    { 
     var reader = t.Result;     

     try     
     {      
      reader.Read(); 
      data.Load(reader); 

      return data; 
     } 
     finally 
     {      
      reader.Dispose(); 
     }    
    } 
    finally 
    { 
     command.Connection.Close(); 
     command.Connection.Dispose(); 
     command.Dispose();     
    } 
}); 
+0

안녕하십니까. 위의 변수를 전달하는 방법을 추가했습니다. 저장 프로 시저 이름 배열과 세 변수를 문자열로 전달하지만 어떤 이유로 스토어드 프로 시저에서 _finYear가 필요하다는 System.AggregateException 오류가 발생합니다. 기묘한! – Beats

+0

제가 생각할 수있는 유일한 추측은 어떻게 든 _finYear에 대해 null 값을 얻었습니다. 디버거에서 실행하면 예외가 발생했을 때 중단되어야하며 _finYear 값을 확인할 수 있습니다. –