my requirement is need to abort the backgroundworker operation while click abort button in alertbox(attached imageExport). Because GetData() will take more time to execute.
if Dowork method is called no need to access the UI element which means we need to restrict that until the backgroundworker completed.So I put Application.Current.Dispatcher. If I remove that(Application.current.dispatcher) line we can access UI elements and do perform some actions, but we need to restrict that while perform dowork event.
Any solution for this,
try
{
var backGroundWorker = new CancelSupportedBackgroundWorker { WorkerSupportsCancellation = true };
CancellationTokenSource source = new CancellationTokenSource();
var alertBox = new AlertBox
{
IsBusy = true,
WaitingText ="Export Data"
WaitingHeaderText ="Exporting"
};
alertBox.AbortButton.Click += (obj, args) =>
{
source.Cancel();
backGroundWorker.CancelAsync();
backGroundWorker.Abort();
backGroundWorker.Dispose();
GC.Collect();
};
backGroundWorker.DoWork += (obj, args) =>
{
Appliction.Current.Dispatcher.Invoke(DispatcherPriority.ApplicationIdle, new Action(
delegate
{
table = GetData((CancellationToken)args.Argument);
if (source.Token != default(CancellationToken))
if (source.Token.IsCancellationRequested)
return;
}));
};
backGroundWorker.RunWorkerCompleted += (obj, args) =>
{
alertBox.IsBusy = false;
};
backGroundWorker.RunWorkerAsync(source.Token);
}
Thanks in advance.
I made an edit, passing an token argument to Dowork event
Clear Requirement is:
1) query operation is need to run in background
2) We cannot access the Other UI elements like File menu items
3) Access only the abort button in alertbox while performing query
If abort button is clicked it will automatically cancel the background operation.
I made an edit using Task.Run() method
Task backgroundTask = null;
try
{
CancellationTokenSource source = new CancellationTokenSource();
var alertBox = new AlertBox
{
IsBusy = true,
WaitingText ="Export Data"
WaitingHeaderText ="Exporting"
};
alertBox.AbortButton.Click += (obj, arg) =>
{
source.Cancel();
GC.Collect();
};
backgroundTask = Task.Run(() => table = GetFullData(source.Token));
IWorkBook.ImportDataTable(table, true, 1, 1, true);
}
catch (ThreadAbortException)
{
}
I made an change for adding GetFullData() method
internal DataTable GetFullData(CancellationToken token)
{
DataTable dataTable = new DataTable();
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
var command = connection.CreateCommand();
command.CommandText = query;
if (QueryParameters != null && QueryParameters.Count > 0)
{
foreach (var parameter in QueryParameters)
{
var param = command.CreateParameter();
param.ParameterName = "@" + parameter.Name.TrimStart('@');
if (string.IsNullOrEmpty(parameter.Value))
{
param.Value = DBNull.Value;
}
else
{
param.Value = parameter.Value;
}
command.Parameters.Add(param);
}
command.GetPreparedSql();
}
command.Connection = connection;
if (connection.State != ConnectionState.Open)
{
connection.Open();
}
var reader = command.ExecuteReader();
var dataTable = new DataTable();
if (token != default(CancellationToken))
token.ThrowIfCancellationRequested();
dataTable.Load(reader);
return dataTable;
}