2017-07-19 21 views
-1

enter image description here我知道这不是关于访问UI线程的第一个问题,但我没有找到解决我的问题的答案。如何使用Dispatcher访问UI元素而Backgroundworker?

在调用示例方法时,它将显示如带有中止按钮的消息框。如果我单击中止按钮,它将不会点击abortbutton单击事件。在这种情况下,alertbox UI冻结。所以我们不能点击该按钮。

如果我删除了调度程序行它将工作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); 

}

+0

此外,我将改变调度优先级为各种类型你为什么要使用一个BackgroundWorker,如果你经常使用调度调用在不同的线程的动作就不会工作 – Pandi

+1

? –

+0

@lan H,我需要使用do work method的结果来设置报表。 – Pandi

回答

0

尽量不要把整个DoWork方法的调度电话里面,而是只要求它一次操作。

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

@lan H,我试着按照你的解决方案。但是alertbox中的中止按钮在点击时无法点击。我也附上有问题的警报箱图像 – Pandi