Reputation: 329
I was wondering why the exception in this Click
event is not being caught? Nothing fancy in the code, except for statusLabel
displaying the status of the process to the user. myDataTable
is a local variable; the goal is to assign the result to it.
Does GetDataTable
have to be asynchronous as well?
public DataTable GetDataTable(string connectionString, string cmdText)
{
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString)) {
using (SqlCommand comm = new SqlCommand(cmdText, conn)) {
conn.Open();
dt.Load(comm.ExecuteReader);
return dt;
}
}
}
private async void Button1_Click(object sender, EventArgs e)
{
try {
statusLabel.Text = "Processing...";
Task<DataTable> dtTask = Task.Run(() => GetDataTable(connectionString, commandText));
await dtTask;
myDataTable = dtTask.Result;
statusLabel.Text = "Done!";
} catch (Exception ex) {
MessageBox.Show("Error");
}
}
UPDATE
I managed to do solve this problem by making GetDataTable()
return a Task
of DataTable
and changing both .Open
and .ExecuteReader
to their asynchronous counterparts. For the other method, those three lines inside the Try
block I reduced to one:
myDataTable = await GetDataTable(connectionString, commandText);
Thanks to everyone's patiences!
Upvotes: 2
Views: 256
Reputation: 131219
Instead of using Task.Run
to convert a synchronous method to an asynchronous one, use ExecuteReaderAsync
to truly load data asynchronously. After that, your code becomes a lot simpler:
public async Task<DataTable> GetDataTable(string connectionString, string cmdText)
{
DataTable dt = new DataTable();
using (SqlConnection conn = new SqlConnection(connectionString)) {
using (SqlCommand comm = new SqlCommand(cmdText, conn)) {
conn.Open();
var reader=await comm.ExecuteReaderAsync();
dt.Load(reader);
return dt;
}
}
}
private async void Button1_Click(object sender, EventArgs e)
{
try {
statusLabel.Text = "Processing...";
myDataTable = await GetDataTable(connectionString, commandText);
statusLabel.Text = "Done!";
} catch (Exception ex) {
MessageBox.Show("Error");
}
}
GetDataTable
became an asynchronous method that executes the query asynchronously and returns a reader with:
var reader=await comm.ExecuteReaderAsync();
dt.Load(reader);
return dt;
After that, setting the myDataTable
variable only requires using an await
:
myDataTable = await GetDataTable(connectionString, commandText);
Upvotes: 1
Reputation: 1367
I believe the answer you are looking for is here: Async void exception handling
I'm assuming that the 'Button1_Click' method was meant to be 'async void'?:
private async void Button1_Click(object sender, EventArgs e)
{
...
}
Upvotes: 0