0

私はC#で書かれたクラスを持っています。その中で、リスト上で特定の関数を並行して実行したいと思います。各項目が完了したら、プログレスバーを更新したいと思います。しかし、私は自分のプログラムから非常に奇妙な振る舞いをします。イベントを実行してサブに到達しますが、実際にコードを実行することはありません。代わりに、フリーズします。(私はvb.netとc#を混ぜました。それはいつか書き直されるでしょう)

だから私のウィンドウフォームで私は呼び出す

    progressBar.Visible = True
    progressBar.Value = 0
    progressBar.Maximum = dataGrid.SelectedRows.Count

    AddHandler quoteManager.refreshStarted, AddressOf progressBarCounter
    quoteManager.refreshAllAsync(list)

イベントは単純です

Private Sub progressBarCounter()
    Me.Invoke(Sub()
                  If progressBar.Value = progressBar.Maximum Then
                      progressBar.Visible = False
                  Else
                      progressBar.Value += 1
                  End If
              End Sub)
End Sub

見積もりマネージャークラスでは、これを定義しています。

    public event Action refreshStarted;

    public void refreshAllAsync(List<BindableQuote> bindableQuotes)
    {
        bindableQuotes.AsParallel()
            .WithDegreeOfParallelism(10)
            .ForAll((quote) => {
                quote.refreshAll();
                if (refreshStarted != null) { refreshStarted(); }
            });
    }

そのため、何らかの理由で、リスト内の各アイテムにprogressBarCounterと入力するようになりましたが、存在しません。代わりに、フォームを凍結したままにします。

4

2 に答える 2

0

これが何が起こっているのか正確にはわかりませんが、Invokeを呼び出しているため、progressBarCounterがブロックしているようです。代わりにBeginInvokeを使用する必要がありますか?BeginInvokeを使用すると、デッドロックの問題が解決する場合があります。この投稿を参照してください:Invoke()とBeginInvoke()の違いは何ですか

于 2010-11-26T20:25:51.567 に答える
0

ここで起こっているように見えるのは、複数のスレッドから UI オブジェクトにアクセスしていることです。

それはサポートされていません。このコードをワーカー スレッドで実行し、何らかの方法で進行状況を蓄積させ、メッセージを UI スレッドに送り返す必要があります。このBackgroundWorkerクラスは、UI スレッドへのマーシャリングを実装するのに役立ちます。

于 2010-11-26T20:10:53.470 に答える