那么,为什么这不会成为回调函数呢?
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";
}
}
}
}
答案 0 :(得分:3)
我认为在读者可以工作之前关闭了连接......
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'?
答案 1 :(得分:3)
我注意到的一些观点:
- 只有在我删除了WAITFOR DELAY后才调用回调方法 语句。
- 没有必要轮询result.IsCompleted,因为 回调方法只在被激活后被触发 异步处理完成。
- 无需在else部分中显式设置dr = null,因为默认情况下 将为空。
- 您应该处理InvalidOperationException和 ArgumentException中的 HandleCallback方法。
- 在句柄回调中,每次都调用EndExecuteReader() 不断获得例外“The 异步操作已经存在 完成了。“所以我永远无法得到 结果在博士。
醇>
如果您遇到点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)
{
...
}
}