Cannot access the AbortButton while doing background operation

Viewed 82

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;
    }
2 Answers
Related