sql异步查询问题

那么,为什么这不会成为回调函数呢?

using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.SqlClient; namespace sqlAsyncTesting { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { using (SqlConnection conn = new SqlConnection(@"Data Source = bigapple; Initial Catalog = master; Integrated Security = SSPI; Asynchronous Processing = true;")) { conn.Open(); SqlCommand cmd = new SqlCommand(@"WAITFOR DELAY '00:03'; Select top 3 * from sysobjects;", conn); IAsyncResult result = cmd.BeginExecuteReader(new AsyncCallback(HandleCallback), cmd, CommandBehavior.CloseConnection); } } private void HandleCallback(IAsyncResult result) { SqlDataReader dr; SqlCommand _this = (SqlCommand)result.AsyncState; if (result.IsCompleted) { dr = _this.EndExecuteReader(result); } else dr = null; DataTable dt = new DataTable(); DataSet ds = new DataSet(); dt.Load(dr); ds.Tables.Add(dt); dr.Close(); Complete(ds); } private void Complete(DataSet ds) { string output = string.Empty; foreach (DataColumn c in ds.Tables[0].Columns) { output += c.ColumnName + "\t"; } output += "\r\n"; foreach (DataRow dr in ds.Tables[0].Rows) { foreach (object i in dr.ItemArray) { output += i.ToString() + "\t"; } output += "\r\n"; } } } 

}

我注意到的一些观点:

  1. 仅在我删除了WAITFOR DELAY stmt之后才调用回调方法。
  2. 无需轮询result.IsCompleted,因为只有在异步处理完成后才会触发Callback方法。
  3. 无需在else部分中显式设置dr = null,因为默认情况下它将为null。
  4. 您应该在HandleCallback方法中处理InvalidOperationException和ArgumentException。
  5. 在句柄回调中,每当调用EndExecuteReader()时,我都会得到exception“异步操作已经完成”。 所以我从来没有能够得到博士的结果。

如果您遇到点no中列出的问题。 5,您可以使用以下备用解决方案,通过使用异步委托而不是内置的BeginExecuteReader()和EndExecuteReader()来实现。 在下面的解决方案中,控件将在调用委托后立即返回到下一行,就像在BeginExecuteReader()的情况下一样。

替代解决方案:

 public partial class Form2 : Form { public Form2() { InitializeComponent(); } private delegate DataSet GetDSDelegate(string query); private void button1_Click(object sender, EventArgs e) { GetDSDelegate del = new GetDSDelegate(GetDataSetAsync); del.BeginInvoke(@"Select top 3 * from table1;", null, null); } private DataSet GetDataSetAsync(string query) { DataSet ds; using (SqlConnection conn = new SqlConnection(@"Data Source = mmmmm000011\sqlexpress; Initial Catalog = SOExamples; Integrated Security = SSPI; Asynchronous Processing = true;")) using (SqlCommand cmd = new SqlCommand(query, conn)) { try { conn.Open(); SqlDataReader dr = cmd.ExecuteReader(); DataTable dt = new DataTable(); ds = new DataSet(); dt.Load(dr); ds.Tables.Add(dt); dr.Close(); Complete(ds); } finally { if (conn.State != ConnectionState.Closed) conn.Close(); } } MessageBox.Show("Done!!!"); return ds; } private void Complete(DataSet ds) { ... } } 

我认为在读者能够工作之前,这种联系正在关闭……

 using (SqlConnection conn = new SqlConnection(@"Data Source = bigapple; Initial Catalog = master; Integrated Security = SSPI; Asynchronous Processing = true;")) 

尝试将其更改为…

 SqlConnection conn = new SqlConnection(@"Data Source = bigapple; Initial Catalog = master; Integrated Security = SSPI; Asynchronous Processing = true;"); conn.Open(); SqlCommand cmd = new SqlCommand(@"WAITFOR DELAY '00:03'; Select top 3 * from sysobjects;", conn); IAsyncResult result = cmd.BeginExecuteReader(new AsyncCallback(HandleCallback), cmd, CommandBehavior.CloseConnection); 

顺便说一下,这段代码等了3分钟? 因为暂停3秒不应该是WAITFOR DELAY’0:0:3’?