WPF: асинхронный индикатор выполнения - PullRequest
3 голосов
/ 20 июля 2009

Я пытаюсь создать индикатор выполнения, который будет работать асинхронно с основным процессом. Я создал новое событие и вызвал его, однако каждый раз, когда я пытаюсь выполнить операции с индикатором выполнения, получаю следующую ошибку:

"Вызывающий поток не может получить доступ к этому объекту, поскольку он принадлежит другому потоку"

Следующий код является попыткой отправить экземпляр индикатора выполнения на событие как объект, он, очевидно, не удался, но дает представление о том, как выглядит код.

    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 ]

5 голосов
/ 20 июля 2009

Вы должны использовать что-то вроде этого

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

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

                        pb.Value += 10;
                    }
                ));

в вашем цикле while

0 голосов
/ 27 августа 2011

Мне больше нравится использовать MVVM и BackgroundWorker. Вот пример того, как это сделать.

Индикатор выполнения с использованием WPF ProgressBar Control, BackgroundWorker и MVVM

0 голосов
/ 21 июля 2009

Я рассмотрел это далее, и асинхронный метод будет работать так же, как и следующий метод из 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);

Моя проблема заключалась в том, что я выполнял хранимую процедуру, когда хотел, чтобы индикатор выполнения выполнялся, и это задерживает процесс и, следовательно, делает индикатор выполнения немного мусором, даже когда он асинхронный.

Полагаю, другой возможностью было бы сделать действия хранимой процедуры асинхронными, как вы думаете, ребята?

Cheers, SumGuy

Редактировать (17 мая 2010 г.)

Кажется, многие люди интересуются этим сообщением, поэтому я решил добавить это. Я нашел отличную статью, в которой очень подробно описывается асинхронная работа в WPF, а также немного полезных индикаторов выполнения:

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

0 голосов
/ 20 июля 2009

Вам необходимо делегировать pbDataImport диспетчеру. Только GUI-диспетчер может вносить изменения в элементы управления GUI:)

...