/// <summary> /// <paramref name="sqlCommand"/> 를 이용하여, <see cref="Task{SqlDataReader}"/>를 반환받습니다. /// 받환받은 DataReader는 꼭 Dispose() 해 주어야 Connection이 닫힙니다. /// </summary> /// <param name="sqlDatabase">DAAB의 SQL Server용 Database</param> /// <param name="sqlCommand">실행할 sqlCommand 인스턴스</param> /// <param name="parameters">Command Parameters</param> /// <returns></returns> public static Task <SqlDataReader> ExecuteReaderAsync(this SqlDatabase sqlDatabase, SqlCommand sqlCommand, params IAdoParameter[] parameters) { sqlCommand.ShouldNotBeNull("sqlCommand"); if (IsDebugEnabled) { log.Debug("ExecuteReader 를 비동기 방식으로 실행합니다... CommandText=[{0}], Parameters=[{1}]", sqlCommand.CommandText, parameters.CollectionToString()); } var newConnectionCreated = false; if (sqlCommand.Connection == null) { sqlCommand.Connection = SqlTool.CreateSqlConnection(sqlDatabase, ref newConnectionCreated); } if (parameters != null) { AdoTool.SetParameterValues(sqlDatabase, sqlCommand, parameters); } var commandBehavior = newConnectionCreated ? CommandBehavior.CloseConnection : CommandBehavior.Default; var tcs = new TaskCompletionSource <SqlDataReader>(); sqlCommand.BeginExecuteReader(iar => { try { tcs.TrySetResult(sqlCommand.EndExecuteReader(iar)); } catch (Exception ex) { tcs.TrySetException(ex); } }, null, commandBehavior); return(tcs.Task); //! NOTE: FromAsync를 사용하지 못한 이유가 sqlCommand.BeginExecuteReader() 의 overloading이 많아서, 모호한 함수 호출 때문이다. //var ar = sqlCommand.BeginExecuteReader(commandBehavior); //return Task.Factory.StartNew(() => sqlCommand.EndExecuteReader(ar)); //Task<SqlDataReader>.Factory.StartNew(state => sqlCommand.EndExecuteReader((IAsyncResult)state), // ar, // TaskCreationOptions.None); }
/// <summary> /// <see cref="SqlCommand.ExecuteXmlReader"/> 를 비동기 방식으로 실행하는 <see cref="Task{XmlReader}"/> 를 빌드합니다. /// </summary> /// <param name="sqlDatabase">DAAB Database 인스턴스</param> /// <param name="sqlCommand">실행할 sqlCommand 인스턴스</param> /// <param name="disposeCommandWhenCompleted">작업 완료 후 command를 dispose할 것인가?</param> /// <param name="parameters">Command paramters</param> /// <returns>비동기 실행용 <see cref="Task{XmlReader}"/></returns> public static Task <XmlReader> ExecuteXmlReaderAsync(this SqlDatabase sqlDatabase, SqlCommand sqlCommand, bool disposeCommandWhenCompleted, params IAdoParameter[] parameters) { sqlCommand.ShouldNotBeNull("sqlCommand"); if (IsDebugEnabled) { log.Debug("sqlCommand.ExecuteXmlReader를 비동기 방식으로 실행합니다... CommandText=[{0}], parameters=[{1}]", sqlCommand.CommandText, parameters.CollectionToString()); } var newConnectionCreated = false; if (sqlCommand.Connection == null) { sqlCommand.Connection = SqlTool.CreateSqlConnection(sqlDatabase, ref newConnectionCreated); } if (parameters != null) { AdoTool.SetParameterValues(sqlDatabase, sqlCommand, parameters); } return (Task.Factory .StartNew(() => sqlCommand.ExecuteXmlReader(), TaskCreationOptions.PreferFairness) .ContinueWith(antecedent => { if (IsDebugEnabled) { log.Debug("sqlCommand.ExecuteXmlReader를 비동기 방식으로 실행했습니다!!! CommandText=[{0}]", sqlCommand.CommandText); } if (newConnectionCreated) { AdoTool.ForceCloseConnection(sqlCommand); } if (disposeCommandWhenCompleted) { With.TryAction(sqlCommand.Dispose); } return antecedent.Result; }, TaskContinuationOptions.ExecuteSynchronously)); }
/// <summary> /// <see cref="SqlCommand"/>을 ExecuteNonQuery 메소드로 비동기 실행을 하도록 하는 <see cref="Task{Int32}"/>를 빌드합니다. /// </summary> /// <param name="sqlDatabase">DAAB의 MS SQL Server용 Database 인스턴스</param> /// <param name="sqlCommand">실행할 SqlComnnad 인스턴스</param> /// <param name="parameters">파리미터 정보</param> /// <returns>실행에 영향을 받은 행의 수를 결과로 가지는 <see cref="Task{Int32}"/></returns> public static Task <int> ExecuteNonQueryAsync(this SqlDatabase sqlDatabase, SqlCommand sqlCommand, params IAdoParameter[] parameters) { sqlCommand.ShouldNotBeNull("sqlCommand"); if (IsDebugEnabled) { log.Debug("sqlCommand.ExecuteNonQuery를 비동기 방식으로 실행합니다. CommandText=[{0}], Parameters=[{1}]", sqlCommand.CommandText, sqlCommand.Parameters.CollectionToString()); } var newConnectionCreated = false; if (sqlCommand.Connection == null) { sqlCommand.Connection = SqlTool.CreateSqlConnection(sqlDatabase, ref newConnectionCreated); } if (parameters != null) { AdoTool.SetParameterValues(sqlDatabase, sqlCommand, parameters); } //! NOTE: FromAsync 메소드에서는 TaskCreationOptions.None 만 가능하다. // return (Task <int> .Factory .FromAsync(sqlCommand.BeginExecuteNonQuery, sqlCommand.EndExecuteNonQuery, null) .ContinueWith(task => { if (newConnectionCreated) { AdoTool.ForceCloseConnection(sqlCommand); } return task; }, TaskContinuationOptions.ExecuteSynchronously) .Unwrap()); }
/// <summary> /// <paramref name="sqlCommand"/> 를 비동기 방식으로 실행하여, Scalar 값을 반환하는 <see cref="Task{Object}"/>를 빌드합니다. /// </summary> /// <param name="sqlDatabase">DAAB의 SQL Server용 Database</param> /// <param name="sqlCommand">실행할 sqlCommand 인스턴스</param> /// <param name="parameters">Command Parameters</param> /// <returns>결과 Scalar 값을 가지는 Task의 인스턴스</returns> public static Task <object> ExecuteScalarAsync(this SqlDatabase sqlDatabase, SqlCommand sqlCommand, params IAdoParameter[] parameters) { sqlCommand.ShouldNotBeNull("sqlCommand"); if (IsDebugEnabled) { log.Debug("sqlCommand.ExecuteScalar 를 비동기 방식으로 실행합니다. CommandText=[{0}], Parameters=[{1}]", sqlCommand.CommandText, parameters.CollectionToString()); } var newConnectionCreated = false; if (sqlCommand.Connection == null) { sqlCommand.Connection = SqlTool.CreateSqlConnection(sqlDatabase, ref newConnectionCreated); } if (parameters != null) { AdoTool.SetParameterValues(sqlDatabase, sqlCommand, parameters); } return (Task.Factory .StartNew(() => sqlCommand.ExecuteScalar()) .ContinueWith(task => { if (newConnectionCreated) { AdoTool.ForceCloseConnection(sqlCommand); } return task; }, TaskContinuationOptions.ExecuteSynchronously) .Unwrap()); }