【问题标题】:WPF BackGroundWorker ProgressChanged not updating textblockWPF BackGroundWorker ProgressChanged 不更新文本块
【发布时间】:2010-05-31 09:57:58
【问题描述】:

我有下面的方法似乎表现得很奇怪。 ProgressChangedRunWorkerCompleted 似乎在同时更新自己。如果我注释掉更新文本块的RunWorkerCompleted 代码,我会看到ProgressChanged 在数据传输后生效。我在这里做错了什么?我显然希望文本块显示我正在获取数据,然后在我完成获取数据后进行更改。

public void GetAppointmentsBackground()
{
   System.Windows.Threading.Dispatcher webServiceDispatcher = this.Dispatcher;
   worker = new BackgroundWorker();
   worker.WorkerReportsProgress = true;
   worker.DoWork += delegate(object sender, DoWorkEventArgs args)
   {
     GetAppointmentsForDayDelegate getAppt = new GetAppointmentsForDayDelegate(GetAppointmentsForDay);
     webServiceDispatcher.BeginInvoke(getAppt);
     (sender as BackgroundWorker).ReportProgress(25);
   };

   worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args)
   {
     txtMessages.Text = "Contacting Server";
   };

   worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args)
   {
     txtMessages.Text = "Completed Successfully";
   };

   worker.RunWorkerAsync();
}

【问题讨论】:

    标签: wpf backgroundworker


    【解决方案1】:

    事实上,System.Windows.Controls 使用了另一个模型(与 Windows.Forms.Control 后代不同)。 我用过类似的东西:

    public delegate void NoArgs();
    
    //...
    
    txtBlock.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, 
        new NoArgs(UpdateTextBlock));
    
    //...
    
    void UpdateTextBlock()
    {
        txtBlock.Text = "Contacting Server";
    }
    

    阅读有关DispatcherDispatcherObject的手册。

    【讨论】:

      【解决方案2】:

      我建议您将其包含在 try{...}catch 块中...和 ​​using 子句中,如下所示

      公共无效GetAppointmentsBackground() { System.Windows.Threading.Dispatcher webServiceDispatcher = this.Dispatcher; 尝试 { 使用 (BackgroundWorker worker = new BackgroundWorker()) { worker.WorkerReportsProgress = true; worker.DoWork += 委托(对象发送者,DoWorkEventArgs args) { GetAppointmentsForDayDelegate getAppt = new GetAppointmentsForDayDelegate(GetAppointmentsForDay); webServiceDispatcher.BeginInvoke(getAppt); (作为 BackgroundWorker 的发送者).ReportProgress(25); }; worker.ProgressChanged += delegate(object s, ProgressChangedEventArgs args) { txtMessages.Text = "联系服务器"; }; worker.RunWorkerCompleted += delegate(object s, RunWorkerCompletedEventArgs args) { 如果(txtMessages.InvokeRequired) { txtMessages.BeginInvoke(新 MethodInvoker(委托() { txtMessages.Text = "成功完成"; })); } 别的 { txtMessages.Text = "成功完成"; } }; worker.RunWorkerAsync(); } } 捕获(异常 eX) { /* 在这里查看是否抛出异常 */ } }

      如果没有抛出异常,可能是在RunWorkerCompleted事件处理程序中使用如上所示txtMessages类的BeginInvoke方法,因为尝试更新@987654326时可能会出现跨线程错误@ 来自 backgroundworker 类的自身。

      【讨论】:

      • 我试过了,没有抛出异常。顺便说一句,我没有将“InvokeRequired”视为 TextBlock 类的属性。在为此熬了一夜之后,我想我最好直接使用调度程序并调用,这样我才能获得生命。
      猜你喜欢
      • 1970-01-01
      • 2020-05-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多