EDIT: The solution that ended up working for me was to use the asynchronous ADO.NET methods. BeginExecute...
and EndExecute...
Here is a snippet of code that asynchronously performs a query while checking whether a BackgroundWorker
has requested cancellation. The function returns true if the query ran to completion, and false if a cancellation was performed.
The code should be called from somewhere within the BackgroundWorker
's DoWork
function.
SqlCommand command = new SqlCommand(query, connectionObj);
IAsyncResult result = command.BeginExecuteReader(); // end async execution
// check for user cancellation while result is not complete
while (!result.IsCompleted)
{
if (myBackgroundWorker.CancellationPending)
{
command.Cancel(); // cancel the existing command
try
{
command.EndExecuteReader(result); // cancel async execution
}
catch (SqlException e)
{
// will always enter here due to command.Cancel()
// this is expected
}
return false;
}
Thread.Sleep(100); // sleep so loop doesn't consume all the resources
}
// result is complete, do something with data
using (SqlDataReader reader = command.EndExecuteReader(result))
{
DataTable table = new DataTable();
table.Load(reader);
}
// do something with table
return true;