2

次のように、「CurrProgress」フィールドと「Total」フィールドにバインドされたプログレスバーがあります。

    <ProgressBar Height="29" HorizontalAlignment="Left" Margin="12,32,0,0" Name="pbSendingData" VerticalAlignment="Top" Width="346"">
        <ProgressBar.Value>
            <Binding ElementName="this" Path="CurrProgress" />
        </ProgressBar.Value>
        <ProgressBar.Maximum>
            <Binding ElementName="this" Path="Total" />
        </ProgressBar.Maximum>
    </ProgressBar>

また、UIの応答性を維持しようとしているときに、手間のかかる作業を行う「ワーカースレッド」もあります。

    private void worker_DoWork(object sender, DoWorkEventArgs e)
    {          
        const int sizeOfPacket = 30;
        Total = allEntries.Count();

        var arrayOfEntries = Split(allEntries, sizeOfPacket); //Split array into small arrays

        //Send parts to server separately:
        foreach (var entries in arrayOfEntries)
        {
            svc.ProcessPMData(Globals.username, Globals.password, entries.ToArray());
            CurrProgress += sizeOfPacket;
            Thread.Sleep(100);
        }

        Thread.Sleep(100);
    }

「Total」および「CurrProgress」依存関係プロパティがスレッドセーフであることを確認しました(正しく実行していない可能性があります)。

    //Dependency properties:
    public int CurrProgress
    {
        get
        {
            return (int)this.Dispatcher.Invoke(
                DispatcherPriority.Background,
                (DispatcherOperationCallback)delegate
                {
                    return GetValue(CurrProgressProperty);
                }, CurrProgressProperty);

        }

        set
        {
            this.Dispatcher.BeginInvoke(DispatcherPriority.Background,
                (SendOrPostCallback)delegate { SetValue(CurrProgressProperty, value); },
                value);
        }
    }


    public static readonly DependencyProperty CurrProgressProperty =
        DependencyProperty.Register("CurrProgress", typeof(int), typeof(DataSender), new PropertyMetadata(0));


    public int Total
    {
        get
        {
            return (int)this.Dispatcher.Invoke(
                DispatcherPriority.Background,
                (DispatcherOperationCallback)delegate
                {
                    return GetValue(TotalProperty);
                }, TotalProperty);

        }

        set
        {
            this.Dispatcher.BeginInvoke(DispatcherPriority.Background,
                (SendOrPostCallback)delegate { SetValue(TotalProperty, value); },
                value);
        }
    }

    public static readonly DependencyProperty TotalProperty =
        DependencyProperty.Register("Total", typeof(int), typeof(DataSender), new PropertyMetadata(0));

デバッグしようとしたとき、私は最初にイミディエイトウィンドウからプログレスバーの値を確認しようとしました。

pbSendingData.Value

このエラーメッセージが表示されました...

ここに画像の説明を入力してください

エラーは理にかなっているので、別の方法を試しました。

this.Dispatcher.Invoke((Action)(() =>      {   MessageBox.Show(pbSendingData.Minimum);     }));

この時点で、イミディエイトウィンドウがラムダ式をサポートしていないことを発見しました。

ウォッチウィンドウも役に立ちませんでした:

ここに画像の説明を入力してください

デバッグ中に、別のスレッドのイミディエイト/ウォッチウィンドウからUIコンポーネントの値を取得したいと思います。これは可能ですか?補足として、私のコードにスキャンダラスなものがあれば、私は提案を受け入れます。私はWPFに少し慣れていません。

4

1 に答える 1

1
  1. プログレスバープロパティのバインディングで参照しているこの「this」要素は何ですか?

  2. 私が見るほとんどのコードは、ディスパッチャーとワーカースレッドからのデリゲートを使用しており、プロパティのゲッター/セッター内ではありません。これは、いくつかの醜い競合状態やデッドロック、または同様の厄介なものをもたらす可能性があるためです。

  3. 「DoWork」メソッドはBackGroundWorkerクラスに属しているようです。「ReportProgress」機能を使用してみませんか?スレッドの同期が含まれます...

于 2013-03-13T02:00:23.730 に答える