使用1个DataReader进行多个数据库调用

我只是学习使用Parallel.Invoke()并试图围绕返回多个DataSets()进行思考。例如,让我们采用下面的示例语法 – 我如何为3个DataSets()每一个使用方法ExecuteSqlQuery() DataSets()我需要退货吗?

 protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) { Parallel.Invoke( new Action(GetFirstGraders), new Action(GetSecondGraders), new Action(GetThirdGraders) ); } } private void GetFirstGraders() { datasetttt1stgrade = FirstGraders(); gv1.DataSource = datasetttt1stgrade; gv1.DataBind(); } private void GetSecondGraders() { datasetttt2ndgrade = SecondGraders(); gv2.DataSource = datasetttt2ndgrade; gv2.DataBind(); } private void GetThirdGraders() { datasetttt3rdgrade = ThirdGraders(); gv3.DataSource = datasetttt3rdgrade; gv3.DataBind(); } public DataSet FirstGraders() { datasetttt = new DataSet(); SqlQueryBuilder = new StringBuilder(); SqlQueryBuilder.Append("exec FirstGraders "); datasetttt = ExecuteSqlQuery(databaseConnection, SqlQueryBuilder.ToString()); datagridInfo.DataSource = datasetttt; datagridInfo.DataBind(); } public DataSet SecondGraders() { datasetttt = new DataSet(); SqlQueryBuilder = new StringBuilder(); SqlQueryBuilder.Append("exec SecondGraders "); datasetttt = ExecuteSqlQuery(databaseConnection, SqlQueryBuilder.ToString()); datagridInfo.DataSource = datasetttt; datagridInfo.DataBind(); } public DataSet ThirdGraders() { datasetttt = new DataSet(); SqlQueryBuilder = new StringBuilder(); SqlQueryBuilder.Append("exec ThirdGraders "); datasetttt = ExecuteSqlQuery(databaseConnection, SqlQueryBuilder.ToString()); datagridInfo.DataSource = datasetttt; datagridInfo.DataBind(); } public DataSet ExecuteSqlQuery(string connectionString, string sqlQuery) { try { connstring = System.Configuration.ConfigurationManager.AppSettings[connectionString].ToString(); dbconn = new SqlConnection(connstring); cm = new SqlCommand(sqlQuery, dbconn); dbconn.Open(); cm.CommandTimeout = 0; datasetttt = new DataSet(); da = new SqlDataAdapter(cm); da.Fill(datasetttt, "Data"); return datasetttt; } catch (Exception exception) { throw exception; } finally { dbconn.Close(); cm.Dispose(); da.Dispose(); } } 

我的这个项目的目标框架是Net Framework 4

尝试此解决方案,看看它是否适用于您的实例。

软件咖啡馆

(请注意,如果网站随时关闭,这是直接复制/粘贴)

 protected void Page_Load(object sender, EventArgs e) { SqlConnection cnn1 = new SqlConnection("Your connection string"); SqlConnection cnn2 = new SqlConnection("Your connection string"); SqlCommand cmd1; SqlCommand cmd2; IAsyncResult result1; IAsyncResult result2; SqlDataReader reader1; SqlDataReader reader2; try { cnn1.Open(); cmd1 = new SqlCommand("SP1", cnn1); cmd1.CommandType = System.Data.CommandType.StoredProcedure; result1 = cmd1.BeginExecuteReader(CommandBehavior.SingleRow); cnn2.Open(); cmd2 = new SqlCommand("SP2", cnn2); cmd2.CommandType = System.Data.CommandType.StoredProcedure; result2 = cmd2.BeginExecuteReader(CommandBehavior.SingleRow); reader1 = cmd1.EndExecuteReader(result1); if (reader1.Read()) { Literal1.Text = reader1[0].ToString(); } reader1.Close(); reader2 = cmd2.EndExecuteReader(result2); if (reader2.Read()) { Literal2.Text = reader2[0].ToString(); } reader2.Close(); } catch (Exception ex) { // raise an exception or do whatever logic you want } finally { if (cnn1.State != System.Data.ConnectionState.Closed) cnn1.Close(); if (cnn2.State != System.Data.ConnectionState.Closed) cnn2.Close(); } } 

我在这台机器上没有编译器,但类似的东西应该允许你为每个存储过程返回一个数据集,或者这至少应该是一个很好的起点。 理想情况下,您希望为每个连接使用using()语句以确保它正确处理,但这又是一个起点

 protected void Page_Load(object sender, EventArgs e) { SqlCommand _sqlCommand1; SqlCommand _sqlCommand2; SqlCommand _sqlCommand3; DataSet ds1 = new DataSet(); DataSet ds2 = new DataSet(); DataSet ds2 = new DataSet(); SqlDataAdapter _sqlDataAdapter1 = new SqlDataAdapter(); SqlDataAdapter _sqlDataAdapter2 = new SqlDataAdapter(); SqlDataAdapter _sqlDataAdapter3 = new SqlDataAdapter(); SqlConnection _sqlDatabaseConnection1; SqlConnection _sqlDatabaseConnection2; SqlConnection _sqlDatabaseConnection3; try { _connectionString = System.Configuration.ConfigurationManager.AppSettings[connectionString].ToString(); _sqlDatabaseConnection1 = new SqlConnection(_connectionString); _sqlCommand1 = new SqlCommand("SP1", _sqlDatabaseConnection1); _sqlDatabaseConnection1.Open(); _sqlCommand1.CommandTimeout = 0; ds1 = new DataSet(); _sqlDataAdapter1 = new SqlDataAdapter(_sqlCommand1); _sqlDataAdapter1.Fill(ds1, "Data"); return ds1; _sqlDatabaseConnection1.Close(); _sqlCommand1.Dispose(); _sqlDataAdapter1.Dispose(); _connectionString = System.Configuration.ConfigurationManager.AppSettings[connectionString].ToString(); _sqlDatabaseConnection2 = new SqlConnection(_connectionString); _sqlCommand2 = new SqlCommand("SP2", _sqlDatabaseConnection1); _sqlDatabaseConnection2.Open(); _sqlCommand2.CommandTimeout = 0; ds2 = new DataSet(); _sqlDataAdapter2 = new SqlDataAdapter(_sqlCommand1); _sqlDataAdapter2.Fill(ds2, "Data"); return ds2; _sqlDatabaseConnection2.Close(); _sqlCommand2.Dispose(); _sqlDataAdapter2.Dispose(); _connectionString = System.Configuration.ConfigurationManager.AppSettings[connectionString].ToString(); _sqlDatabaseConnection3 = new SqlConnection(_connectionString); _sqlCommand3 = new SqlCommand("SP3", _sqlDatabaseConnection1); _sqlDatabaseConnection3.Open(); _sqlCommand3.CommandTimeout = 0; ds2 = new DataSet(); _sqlDataAdapter3 = new SqlDataAdapter(_sqlCommand1); _sqlDataAdapter3.Fill(ds3, "Data"); return ds3; _sqlDatabaseConnection3.Close(); _sqlCommand3.Dispose(); _sqlDataAdapter3.Dispose(); } catch (Exception ex) { } } 

为什么不使用async / await方法并将它们以异步模式注册到页面中? http://www.asp.net/web-forms/overview/performance-and-caching/using-asynchronous-methods-in-aspnet-45

更新 :我将分享使用4.0中的 ASP.NET WebForms执行异步进程的示例。 首先,我定义了一个用于生成PageAsyncTask实例的扩展方法实用程序:

 public static class PageAsyncTaskGenerator { public static PageAsyncTask ToPageAsyncTask(this Task task, Action onTimeout = null) { Func func = () => task; return new PageAsyncTask( (sender, e, cb, extraData) => func.BeginInvoke(cb, extraData), ar => func.EndInvoke(ar).Wait(), ar => { if (onTimeout != null) { onTimeout(ar); } }, null); } } 

然后,在aspx文件中,您需要将Async属性标记为true的页面:

 <%@ Page Language="C#" AutoEventWireup="true" Async="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %> 

然后,在您的代码隐藏中,只需创建一个Task并将其注册为此示例:

 protected void Page_Load(object sender, EventArgs e) { RegisterAsyncTask(LoadDataAsync().ToPageAsyncTask()); } private Task LoadDataAsync() { var t1 = ExecuteQueryAsync(databaseConnection, "exec FirstGraders "); var t2 = ExecuteQueryAsync(databaseConnection, "exec SecondGraders "); var t3 = ExecuteQueryAsync(databaseConnection, "exec ThirdGraders "); return Task.Factory.ContinueWhenAll(new[] { t1, t2, t3 }, _ => { gv1.DataSource = t1.Result; gv1.DataBind(); gv2.DataSource = t2.Result; gv2.DataBind(); gv3.DataSource = t3.Result; gv3.DataBind(); }); } private Task ExecuteSqlQueryAsync(string connectionString, string sqlQuery) { return Task.Factory.StartNew( () => { try { connstring = System.Configuration.ConfigurationManager.AppSettings[connectionString].ToString(); dbconn = new SqlConnection(connstring); cm = new SqlCommand(sqlQuery, dbconn); dbconn.Open(); cm.CommandTimeout = 0; datasetttt = new DataSet(); da = new SqlDataAdapter(cm); da.Fill(datasetttt, "Data"); return datasetttt; } catch (Exception exception) { throw exception; } finally { dbconn.Close(); cm.Dispose(); da.Dispose(); } }); }