Cannot access AbortButton while performing background operation

My requirement is to cancel the background worker operation by clicking the "Cancel" button in the notification window (attached image "Export"). Since GetData () will take longer to execute.

if the Dowork method is not needed to access the user interface element, which means that we need to limit it until the background work is completed. So I put Application.Current.Dispatcher. If I remove this line (Application.current.dispatcher), we can access the user interface elements and perform some actions, but we need to limit this by executing the 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.

, Dowork

:

1)

2) , ""

3)

, .

Task.Run()

     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)
        {

        }

GetFullData()

 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;
    }
+4
2

, , IProgress.

- , , , Task.Run CancellationToken.

frmDoWork 2 cmdDoWork cmdAbort

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsApplication1
{
    public partial class frmDoWork : Form
    {
        CancellationTokenSource cts = null;
        Task backgroundTask = null;

        public frmDoWork()
        {
            InitializeComponent();
        }

        private void WorkToDoInBackgroundThread(IProgress<int> progress, CancellationToken cancellationToken)
        {
            try
            {
                for (int i = 0; i < 10; i++)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    Task.Delay(1000).Wait(cancellationToken);
                    progress.Report(i);
                    System.Diagnostics.Debug.WriteLine($"{i} - {DateTime.Now}");
                }
            }
            catch(OperationCanceledException ex)
            {

            }

        }

        private void cmdDoWork_Click(object sender, EventArgs e)
        {
            cts = new CancellationTokenSource();
            Progress <int> prg= new Progress<int>(x => this.Text = $"Iteration - {x}");

            backgroundTask = Task.Run(()=> WorkToDoInBackgroundThread(prg, cts.Token));
        }

        private void cmdAbort_Click(object sender, EventArgs e)
        {
            cts?.Cancel();
        }
    }
}

, , , , ( ). , cts , reset .

, . .

, , IProgress .

, , . .

{
    AlertBox alertBox = new AlertBox();
    alertBox.Owner = this;
    alertBox.Show();
    alertBox.Closed += (sender, e) => this.IsEnabled = true;
    this.IsEnabled = false;
}
+2

, , isHitTestVisible, .

@Ashley Pillay .

      Window.isHitTestVisible = false;
      alertBox.AbortButton.Click += (obj, args) =>
        {
            Window.IsHitTestVisible = true;
            source.Cancel();
            backGroundWorker.CancelAsync();
            backGroundWorker.Abort();
            backGroundWorker.Dispose();
            GC.Collect();
        };
        backGroundWorker.DoWork += (obj, args) =>                 
        { 
                table = GetData((CancellationToken)args.Argument);

                if (source.Token != default(CancellationToken))
                    if (source.Token.IsCancellationRequested)
                        return;
         };
        backGroundWorker.RunWorkerCompleted += (obj, args) =>
        {
            Window.IsHitTestVisible = true;
            alertBox.IsBusy = false;
        };
0

Source: https://habr.com/ru/post/1682816/


All Articles