【问题标题】:WPF: Asynchronous progress barWPF:异步进度条
【发布时间】:2009-07-20 10:18:45
【问题描述】:

我正在尝试创建一个与主进程异步工作的进度条。我创建了一个新事件并调用它但是每次我尝试在进度条上执行操作时都会收到以下错误:

“调用线程无法访问此对象,因为不同的线程拥有它”

以下代码尝试将进度条的实例作为对象发送到事件,它显然失败了,但它让您了解代码的外观。

    private event EventHandler importing;

    void MdbDataImport_importing(object sender, EventArgs e)
    {
        ProgressBar pb = (ProgressBar)sender;
        while (true)
        {
            if (pb.Value >= 200)
                pb.Value = 0;

            pb.Value += 10;
        }
    }

    private void btnImport_Click(object sender, RoutedEventArgs e)
    {
        importing += new EventHandler(MdbDataImport_importing);
        IAsyncResult aResult = null;

        aResult = importing.BeginInvoke(pbDataImport, null, null, null);

        importing.EndInvoke(aResult);
    }

有没有人知道如何做到这一点。

提前致谢 SumGuy。

【问题讨论】:

    标签: c# wpf events asynchronous event-handling


    【解决方案1】:

    你应该使用这样的东西

    pb.Dispatcher.Invoke(
                      System.Windows.Threading.DispatcherPriority.Normal,
                      new Action(
                        delegate()
                        {
    
                            if (pb.Value >= 200)
                                pb.Value = 0;
    
                            pb.Value += 10;
                        }
                    ));
    

    在你的 while 循环中

    【讨论】:

    • 这确实有效,但它很慢。不知道是不是我做的那样,我得再摸索一下
    • 1) 使用 BeginInvoke 代替 Invoke(您不希望后台处理线程等到 GUI 重新绘制,对吗?) 2) 不要尝试每微秒更新进度,选择合理的间隔.
    【解决方案2】:

    您需要将 pbDataImport 委托给调度程序。只有 GUI 调度程序可以更改 GUI 控件:)

    【讨论】:

      【解决方案3】:

      我已经对其进行了进一步研究,异步方法将与 MSDN 中的以下方法一样工作。

      在 XAML 中:

      <ProgressBar Width="100" Height="20" Name="progressBar1">
          <ProgressBar.Triggers>
              <EventTrigger RoutedEvent="ProgressBar.Loaded">
                  <BeginStoryboard>
                      <Storyboard>
                          <DoubleAnimation Storyboard.TargetName="progressBar1"  From="0" To="100" Duration="0:0:5"  />
                      </Storyboard>
                  </BeginStoryboard>
              </EventTrigger>
          </ProgressBar.Triggers>
      </ProgressBar>
      

      在 C# 中:

              ProgressBar progbar = new ProgressBar();
              progbar.IsIndeterminate = false;
              progbar.Orientation = Orientation.Horizontal;
              progbar.Width = 150;
              progbar.Height = 15;
              Duration duration = new Duration(TimeSpan.FromSeconds(10));
              DoubleAnimation doubleanimation = new DoubleAnimation(100.0, duration);
              progbar.BeginAnimation(ProgressBar.ValueProperty, doubleanimation);
      

      我的问题是,当我希望进度条执行时,我正在执行一个存储过程,这会阻止进程,因此即使在异步时,进度条也有点垃圾。

      我想另一种可能性是使存储过程操作异步,你们怎么看?

      干杯, 总和

      编辑(2010 年 5 月 17 日)

      似乎很多人对这篇文章感兴趣,所以我想我会添加这个。我发现了一篇优秀的文章,它非常详细地描述了 WPF 中的异步工作以及进度条上的一些有趣的内容:

      http://www.codeproject.com/KB/WPF/AsynchronousWPF.aspx

      【讨论】:

      【解决方案4】:

      我更喜欢使用 MVVM 和 BackgroundWorker。这是一个这样做的示例。

      A Progress Bar using WPF’s ProgressBar Control, BackgroundWorker, and MVVM

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-02-17
        • 1970-01-01
        • 1970-01-01
        • 2020-04-30
        • 1970-01-01
        相关资源
        最近更新 更多