0

プログラムに簡単なテキストボックスがあります。その他の機能:ユーザーtextbox1からの別の入力とボタン。ユーザーがtextbox1に値を入力し、ボタンを押すと、ユーザーへのメッセージの確認と印刷を開始します。私の問題は、これらのメッセージが一度に1つずつリアルタイムで表示されないことです。メッセージは、最後に一度に表示されます。私はデータバインディングを定義しませんでした。なぜなら、それは単純なことなので、私はそれを必要としないだろうと思ったからです。それとも私は間違っていますか?これは私のプログラムのごく一部であり、ボタンクリックイベントハンドラーにあります。

MainText.AppendText("Starting Refiling...\u2028");
foreach (DocumentData doc in Docs)
{
    try
    {
        wsProxy.RefileDocument(doc);
        MainText.AppendText(String.Format("Refilling doc # {0}.{1}\u2028", doc.DocNum, doc.DocVer));
    }
    catch (Exception exc)
    {
        if (exc.Message.Contains("Document is in use") == true)
            MainText.AppendText(String.Format("There was a problem refilling doc # {0}, it is in use.\u2028",doc.DocNum));
        else
            MainText.AppendText(String.Format("There was a problem refilling doc # {0} : {1}.\u2028", doc.DocNum, exc.Message));
    }
}
4

1 に答える 1

1

GUIスレッドですべてのループ/印刷を行っています。基本的に、表示する新しいアイテムを与えており、それらを表示する時間を与えていません。バックグラウンド ワーカーを作成し、投稿した foreach ループで作業を実行させます。これにより、すべての変更を最後に 1 回更新するのではなく、テキストが変更されたときに UI スレッドがビューを更新できるようになります。私が投稿したリンクには、backgroundworker クラスの使用方法の例が含まれていますが、これが私が行うことです。

バックグラウンド ワーカーを作成します。

private readonly BackgroundWorker worker = new BackgroundWorker();

彼を初期化します。

public MainWindow()
  {
     InitializeComponent();

     worker.DoWork += worker_DoWork;
  }

彼のためにタスクを作成します。

void worker_DoWork( object sender, DoWorkEventArgs e)
{
   // Set up a string to hold our data so we only need to use the dispatcher in one place
   string toAppend = "";
   foreach (DocumentData doc in Docs)
   {
      toAppend = "";
      try
      {
         wsProxy.RefileDocument(doc);
         toAppend = String.Format("Refilling doc # {0}.{1}\u2028", doc.DocNum, doc.DocVer);  
      }
      catch (Exception exc)
      {
         if (exc.Message.Contains("Document is in use"))
            toAppend = String.Format("There was a problem refilling doc # {0}, it is in use.\u2028",doc.DocNum);
         else
            toAppend = String.Format("There was a problem refilling doc # {0} : {1}.\u2028", doc.DocNum, exc.Message);
      }

      // Update the text from the main thread to avoid exceptions
      Dispatcher.Invoke((Action)delegate
      {
         MainText.AppendText(toAppend);
      });
   }
}

ボタン プレス イベントを取得したときに開始します。

private void Button_Click(object sender, RoutedEventArgs e)
  {
     worker.RunWorkerAsync();
  }
于 2012-07-26T13:15:05.103 に答える