-1

enter image description here I know this is not the first question about access UI thread but I didn't find the answer to solve my problem.

While calling sample method it will display like the message box with abort button.If i click the abort button it will be not hit the abortbutton click event.Here that alertbox UI is freezing.So we can't hit that.

If i remove the dispatcher line it will be work fine.But i want that line for executing AddQueryIntoTable method. If that method will call after 100 milli seconds it will retrive data perfectly.

So i will set 100 ms as sleep mode(Commented line) it will be work fine.But i think this is not the perfect solution for this.

Thanks in advance.

public void SampleMethod()
     {   
        CancelSupportedBackgroundWorker backGroundWorker = new CancelSupportedBackgroundWorker { WorkerSupportsCancellation = true };
        CancellationTokenSource source = new CancellationTokenSource();
        AlertBox alertBox = new AlertBox
        {
            WaitingText = "Loading Indicator",
            WaitingHeaderText = "It is Loading",
        };
        alertBox.IsBusy = true;
        alertBox.AbortButton.Click += (obje, arg) =>
        {
            MessageBox.Show("Hit");
        };
         backGroundWorker.DoWork += (obj, e) =>
        {
        App.Current.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(
             delegate ()
             {
                 try
                 {
                     if (info == null)
                     {
                     //Thread.sleep(100);
                     arg.result = AddqueryintoTable((CancellationToken)e.Argument);

                    if (backGroundWorker.CancellationPending)
                         {
                             e.Cancel = true;
                             return;
                         }
                     }
                 }
                 catch (ThreadAbortException)
                 {
                     Dispatcher.Invoke(() =>
                     {
                         alertBox.IsBusy = false;
                     }, System.Windows.Threading.DispatcherPriority.Background);
                     e.Cancel = true;
                 }
             }));
        };
        backGroundWorker.RunWorkerCompleted += (obj, arg) =>
        {
            if (arg.Cancelled)
            {
                alertBox.IsBusy = false;
                return;
            }
            alertBox.IsBusy = false;      
            if (arg != null && arg.Result != null)
            {
                SetReport(arg.Result);
            }          
        };
        backGroundWorker.RunWorkerAsync(source.Token);

}

Pandi
  • 471
  • 3
  • 17
  • Also i will change the dispatcher priority into various types it will not working – Pandi Jul 19 '17 at 10:21
  • 1
    Why are you using a BackgroundWorker, if you are constantly using the dispatcher to call an action on a different thread? – Ian H. Jul 19 '17 at 10:40
  • @lan H, I need to set report using result of do work method. – Pandi Jul 19 '17 at 10:51
  • 1
    But why are you dispatching **the whole DoWork** method? – Ian H. Jul 19 '17 at 10:53
  • I also try this: if (info == null) { App.Current.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action(delegate () { args.result = AddqueryintoTable((CancellationToken)e.Argument); })); if (backGroundWorker.CancellationPending) { e.Cancel = true; return; } } – Pandi Jul 19 '17 at 10:59
  • @lan H, Do work method just only call the Addqueryintotable method.Here i didn't find any difference between **whole Do work** method and **single line of Dowork** method as dispatching. – Pandi Jul 19 '17 at 11:08
  • 1
    The BackgroundWorker is meant to run _asynchronously_. Here you are invoking your entire `DoWork` method to the dispatcher, making the BackgroundWorker work not asynchronous anymore. – Ian H. Jul 19 '17 at 11:11
  • @lan H, So what i will do for call a AddqueryintoTable method after 100 milli seconds.It need to wait for atleast 100 ms. – Pandi Jul 19 '17 at 11:16

1 Answers1

0

Try not to put the entire DoWork method inside the Dispatcher call, but rather only calling a single operation on it.

backGroundWorker.DoWork += (obj, e) =>
{
    try
    {
        if (info == null)
        {
            Thread.Sleep(100);
            App.Current.Dispatcher.Invoke(DispatcherPriority.SystemIdle, new Action( delegate ()
            {
                arg.result = AddqueryintoTable((CancellationToken)e.Argument);
            }));

            if (backGroundWorker.CancellationPending)
            {
                e.Cancel = true;
                return;
            }
        }
    }
    catch (ThreadAbortException)
    {
        Dispatcher.Invoke(() =>
        {
            alertBox.IsBusy = false;
        }, System.Windows.Threading.DispatcherPriority.Background);
        e.Cancel = true;
    }  
};
Ian H.
  • 3,840
  • 4
  • 30
  • 60
  • @lan H, I tried as per your solution.But the abort button in alertbox doesn't able to hit while click that. I also attach the alertbox image in question – Pandi Jul 19 '17 at 11:29