WPF:异步进度条

时间:2009-07-20 10:18:46

标签: c# wpf events asynchronous event-handling

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

“调用线程无法访问此对象,因为其他线程拥有它”

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

    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。

4 个答案:

答案 0 :(得分:5)

你应该使用这样的东西

pb.Dispatcher.Invoke(
                  System.Windows.Threading.DispatcherPriority.Normal,
                  new Action(
                    delegate()
                    {

                        if (pb.Value >= 200)
                            pb.Value = 0;

                        pb.Value += 10;
                    }
                ));
在你的while循环中

答案 1 :(得分:0)

您需要将pbDataImport委托给调度程序。只有GUI调度程序才能对GUI控件进行更改:)

答案 2 :(得分:0)

我进一步研究过,异步方法和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);

我的问题是,当我想要执行进度条时,我正在执行存储过程,这会保持进程,因此即使在异步时也会使进度条变得有点垃圾。

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

干杯, SumGuy

编辑(2010年5月17日)

似乎很多人都对这篇文章感兴趣所以我想我会加上这个。我找到了一篇非常出色的文章,详细描述了WPF中的异步工作以及进度条上的一些好处:

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

答案 3 :(得分:0)

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

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