Reputation: 63
I am running a SQLQuery that takes roughly 45 seconds to run and display results. I am using Task<DataSet>
to populate two drop downs on my page. Well the 1st drop down populates fine (the query is completed in about 2 seconds), the second it seems that the adapter.Fill(dataSet)
is not waiting on the query to complete before it begins to fill the drop down with a null dataset. What should I alter so that the code execution halts until the query executes completely?
Task.Factory.ContinueWhenAll(new[]
{
One("Data Source=server;Initial Catalog=db;Integrated Security=True;MultipleActiveResultSets=True"),
Two("Data Source=server;Initial Catalog=db;Integrated Security=True;MultipleActiveResultSets=True"),
}, tasks =>
{
try
{
this.ddl1.DataSource = tasks[0].Result.Tables[0];
this.ddl1.DataTextField = "One";
this.ddl1.DataValueField = "ID";
this.ddl1.DataBind();
int indexOfLastItem = this.ddl1.Items.Count - 1;
this.ddl1.SelectedIndex = indexOfLastItem;
ddl2.DataSource = tasks[1].Result.Tables[0];
this.ddl2.DataTextField = "Two";
this.ddl2.DataValueField = "ID";
this.ddl2.DataBind();
this.ddl2.Items.Insert(0, new ListItem(Constants.All, Constants.All));
}
catch (Exception exception) { throw exception; }
}, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
public System.Threading.Tasks.Task<DataSet> One(string databaseConnection)
{
return FillDS("Select * from activeemployees", databaseConnection);
}
public System.Threading.Tasks.Task<DataSet> Two(string databaseConnection)
{
return FillDS("Select * from mastersalesdatabase", databaseConnection);
}
public System.Threading.Tasks.Task<DataSet> FillDS(string sqlQuery, string connectionString)
{
try
{
var dataSet = new DataSet();
using (var adapter = new SqlDataAdapter(sqlQuery, connectionString))
{
adapter.Fill(dataSet);
return dataSet;
}
}
catch (Exception exception) { throw exception; }
}
My query Select * from activeemployees
completes in about 2 seconds and populates fine, my query Select * from mastersalesdatabase
takes roughly 45 seconds and it seems the code just moves on w/o a delay to let the query execute to completion.
Upvotes: 1
Views: 1203
Reputation: 32702
If you're going to do async to retrieve data into a datatable, it should look more like this:
public static async Task<DataTable> GetDataTableAsync(string connectionString, SqlCommand command)
{
using (var connection = new SqlConnection(connectionString))
{
command.Connection = connection;
await connection.OpenAsync();
using (var dataReader = await command.ExecuteReaderAsync())
{
var dataTable = new DataTable();
dataTable.Load(dataReader);
return dataTable;
}
}
}
Notice there's no need for a dataset.
Then in WebForms, we have to handle async code differently.
protected void Page_Load(object sender, EventArgs e)
{
RegisterAsyncTask(new PageAsyncTask(DoWorkAsync));
}
private async Task DoWorkAsync()
{
ActiveEmployeesDropDownList.DataSource = GetDataTableAsync(databaseConnection, new SqlCommand("select * from activeemployees"));
ActiveEmployeesDropDownList.DataBind();
}
Notice I renamed the control from ddl1
to ActiveEmployeesDropDownList
because ddl1
is a horrible name. Your names should have semantic meaning.
You'll need to add the async=true
attribute to your page according to MSDN.
And you should also fix your query to not take 45 seconds, but that's a separate question entirely.
Upvotes: 2