1

WPFでMVCモデルを使用していますが、UIのロックに問題があります。アプリケーションは2つのエンドポイント間で通信しており、UIには通信の詳細なログを書き込むTextBoxがあります。コードは、単一のファイルまたは複数のファイルをバーストで送信する場合があります。

ログを作成、フォーマット、およびディスクに書き込む必要があるため、ログの処理に使用する特定のログクラスがあります。TextBoxをLoggingクラスに渡し、Dispatcherを使用して書き込みますが、同時に複数のログを書き込むと、UIがロックされます。送信された単一のファイルからログを書き込むだけの場合、すべてが正常に機能します。

スレッドロックを追加しようとしましたが、何も修正されていないようです。書き込みプロセス全体(情報の処理、ディスクへの書き込み、UIへの書き込み)をロックしましたが、同じロックの問題が引き続き発生します。

UIへの書き込みに使用するコードを以下に示します。

    /// <summary>
    /// Post the message to the UI.
    /// </summary>
    /// <param name="message">Message to post.</param>
    /// <param name="scrollToEnd">Scroll to the end of the Text Box if true</param>
    private void PostMessage(String message, bool scrollToEnd)
    {
        LoggingBox.Dispatcher.BeginInvoke(
            System.Windows.Threading.DispatcherPriority.Normal,
            new Action(delegate()
                {
                    LoggingBox.AppendText(message);
                    if (scrollToEnd)
                        LoggingBox.ScrollToEnd();
                }
            ));
    }

LogBoxは単なるTextBoxです。

    /// <summary>
    /// Location for logs to be displayed.
    /// </summary>
    public TextBox LoggingBox { get; set; }

WPFを使用するのはこれが初めてなので、私が犯している単純な間違いがあると確信しています。任意の洞察をいただければ幸いです。

4

3 に答える 3

1

最初に変更するのは、ディスパッチャー呼び出しの優先度をバックグラウンドに設定することです。これは、UIが他のすべての雑用で完了した場合にのみ、ログ変更要求が処理されることを意味します。それ以外の場合は、StringBuilderでログエントリを収集し、UIを1秒ごとに更新するだけで、高価な画面更新を節約できます。

于 2012-08-28T18:06:02.140 に答える
0

これDispatcherは単にメインのUIスレッドです。さまざまなDispatcherPrioritiesでプロセスをスケジュールして、タスクの実行時に影響を与えることができますが、それでも単一スレッドであり、重い処理を実行するとUIがロックされます。

このため、すべての重い処理は別のスレッドで実行し、UIスレッドで実際に何かを実行する必要がある場合にのみディスパッチャースレッドに渡す必要があります。

実際には、直接更新するのではなく、プロパティを更新して文字列にstringバインドすることをお勧めします。これにより、すべての処理を別のスレッドで実行でき、まったく心配する必要がなくなります。TextBox.TextTextBoxDispatcher

さらに、デフォルトでTextBoxは、aにはtrueに設定されたIsUndoEnabledプロパティがあります。これにより、テキストへのすべての変更の履歴が保持されるため、元に戻す/やり直しのホットキーを使用できます。バインディングに切り替えたくない場合は、少なくともに設定IsUndoEnabled=falseしてくださいTextBox

そして最後に、hbarckが言ったDispatcherPriorityように、をなどのより低いものに切り替えますDispatcherPriority.Background

于 2012-08-28T18:09:50.280 に答える
0

コードを実行し、さまざまな部分を無効にした後、UIへの投稿がUIのフリーズの原因ではないことに気付きました。作業の大部分を実行したオブジェクトの1つは、元の開発者によって別のスレッドに配置されていませんでした。スレッドを作成した後、UIのフリーズが停止しました。

助けてくれた皆さん、ありがとうございました。ここのコミュニティは素晴らしいです!

于 2012-09-11T16:20:50.220 に答える