如何在使用 Dispatcher 的 Backgroundworker 时访问 UI 元素?

How can I access UI element while Backgroundworker with Dispatcher?

enter image description here 我知道这不是关于访问 UI 线程的第一个问题,但我没有找到解决我问题的答案。

在调用示例方法时,它会像带有中止的消息框一样显示 button.If 我单击中止按钮,它将不会点击中止按钮 event.Here 警报框 UI 是 freezing.So我们打不到那个。

如果我删除调度程序行,它将起作用 fine.But 我希望该行用于执行 AddQueryIntoTable 方法。如果该方法将在 100 毫秒后调用,它将完美地检索数据。

所以我将设置 100 毫秒作为睡眠模式(注释行)它会起作用 fine.But 我认为这不是完美的解决方案。

提前致谢。

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

}

尽量不要将整个 DoWork 方法放在 Dispatcher 调用中,而是只调用其中的一个操作。

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;
    }  
};