2

「findListText」というテキストブロックがあります。ここで、私はその中のテキストを更新しています:

private void InstantSearch(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Return)
    {
        HitEnter = true;
    }
    findListText.Text = "Processing request. Please wait...";
    Find(bool.Parse("False" as string));
}

ただし、次のコードセットは、最大10秒かかる検索関数であり、最後に、findListTextのテキストを再度変更します。

private void Find(bool? bForward = true)
{
    {
        //Lots and lots of code
    }
    findListText.Text = "Search completed."
}

問題は、テキストブロックが「リクエストを処理しています。お待ちください...」に更新されていないように見えることです。テキストブロックは元の状態にあり、10秒後に「検索が完了しました。」に更新され、仲介者をスキップしているようです。

私はC#-WPFを使用しています。私はここで何が間違っているのですか?

4

5 に答える 5

3

どんな技術だと思いますか。

コードは同じスレッドで実行されています。つまり、そのスレッドのすべてのコードが完了するまでUIは更新されません。そのテキストブロックを更新するには、別のスレッドをアドレス指定する必要があります。

その場合、2つのスレッドがあります。

  • 「たくさんのコード」を実行する元のスレッド
  • 2番目の(追加の)作成されたスレッド。他のスレッドが他のコードを実行している間にテキストブロックのテキストの更新を処理します。

私はあなたの問題を解決するはずの小さなものを作成しました、それはこのスタックオーバーフローページに基づいています

于 2012-08-20T11:14:52.800 に答える
1

WPFのUIスレッドの概念を調べる必要があります。を呼び出してDispatcher、テキストボックスを変更します。また、検索はで実行する必要がありThreadPool.QueueWorkerItemます。

// Start worker thread
ThreadPool.QueueUserWorkItem(state =>
{
    // Long running logic here
   findListText.Dispatcher.BeginInvoke(() => findListText.Text = "Processing request. Please wait...");
   Find(bool.Parse("False" as string)); 


    // Tip: Run change on GUI thread from the worker using the dispatcher
    findListText.Dispatcher.BeginInvoke(() => findListText.Text = "Search completed.");
});
于 2012-08-20T11:15:39.300 に答える
1

これはWPFであるため、次のことを試してください。テキストを「Processgin」に変更した後、次を呼び出します。

Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { this.UpdateLayout(); }));

これにより、UIをできるだけ早く更新するようにスレッドに指示されます。

于 2012-08-20T11:17:23.603 に答える
1

findメソッドを独自のスレッドで実行する方法は次のとおりです。

private void InstantSearch(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Return)
    {
        HitEnter = true;
    }
    findListText.Text = "Processing request. Please wait...";
    BackgroundWorker tempWorker = new BackgroundWorker();
    tempWorker.DoWork += delegate
    {
       Find(bool.Parse("False" as string));
    };
    tempWorker.RunWorkerAsync();
}

これを実行しようとすると、バックグラウンドスレッドからUIスレッドにアクセスするため、エラーが発生します。したがって、findメソッドも更新する必要があります。

private void Find(bool? bForward = true)
{
   {
       //Lots and lots of code
   }
   Dispatcher.BeginInvoke((Action) delegate {
      findListText.Text = "Search completed."
   });
}
于 2012-08-20T11:25:35.107 に答える
0

私はちょうど今これに戻って、同様の問題についてインターネットをもう一度閲覧しました。長時間実行されるプロセスが発生する前に単一のメッセージをプッシュするような単純なものについては、誰も「Application.DoEvents();」を提案していないことに驚いています。はい、私はそれが欠陥を持っていることを知っています、そして私のUIはまだハングします、しかしこれは少なくとも私の状況に完全に合っています。

于 2012-08-24T11:30:23.297 に答える