Некоторые моменты, которые я заметил:
- Метод обратного вызова был вызван только после того, как я удалил ЗАДЕРЖКУ ОЖИДАНИЯ
STMT.
- Нет необходимости опрашивать результат. Завершено, потому что
Метод обратного вызова срабатывает только после
Асинхронная обработка завершена.
- Нет необходимости явно устанавливать dr = null в остальной части, потому что по умолчанию это
будет нулевым.
- Вы должны обработать InvalidOperationException и
ArgumentException в
Метод HandleCallback.
- В обратном вызове дескриптора всякий раз, когда EndExecuteReader () вызывался I
продолжал получать исключение "The
асинхронная операция уже
завершен ". Таким образом, я так и не смог получить
результат в др.
Если вы столкнулись с проблемой, указанной в пункте №. 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)
{
...
}
}