1

簡単なテキスト文字列でGUIを定期的に更新する方法を理解したいと思います。基本的に、私は定期的にTwitterをポーリングして更新を行うTwitterアプリケーションを作成しています。更新の内容をテキストブロックに1つずつ一定のループで表示したいと思います。

GUIの応答性を維持するには、バックグラウンドワーカースレッドでクエリを実行する必要がありますが、このスレッドからGUIを更新することはできません。学習者として、私はイベントを使用してGUIを更新する方法を実装するのに苦労しています。

以下の私のコードでは、「MainWindowGoUpdate」が「間違ったスレッド」にあることを理解していますが、GUIスレッドにイベントをリッスンさせるにはどうすればよいですか?

ポインタをいただければ幸いです。

public partial class MainWindow : Window
{
  public MainWindow()
  {
    public static event UpdateTimeLineEvent _goUpdate;

    public static string TheTimeLine;
    UpdateTimeLine();
  }

  private void UpdateTimeLine()
  {        
   txtb_timeline.Text = "Updating...";

   BackgroundWorker startTimelineUpdater = new BackgroundWorker();
   startTimelineUpdater.DoWork += new DoWorkEventHandler(startTimelineUpdater_DoWork);
   startTimelineUpdater.RunWorkerCompleted += new RunWorkerCompletedEventHandler(startTimelineUpdater_RunWorkerCompleted);
   startTimelineUpdater.RunWorkerAsync();        
  }

  void startTimelineUpdater_DoWork(object sender, DoWorkEventArgs e)
  {
    while (true)
    {
      Xtweet getSQL = new Xtweet();
      var sqlset = getSQL.CollectLocalTimelineSql();

      int i = 0;
      while (i < 10)
      {
        foreach (var stringse in sqlset)
        {
          StringBuilder sb = new StringBuilder();

          sb.Append(stringse[0] + ": ");
          sb.Append(stringse[1] + " @ ");
          sb.Append(stringse[2]);

          sb.Append("\n");

          TheTimeLine = sb.ToString();

          _goUpdate += new UpdateTimeLineEvent(MainWindowGoUpdate);
          _goUpdate.Invoke();

          Thread.Sleep(10000);
          i++;
        } 
      } 
    }        
  }
  void MainWindowGoUpdate()
  {
    txtb_timeline.Text = TheTimeLine;
  }
  void startTimelineUpdater_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  {
    txtb_timeline.Text = "should not see this";
  }  
 }
4

4 に答える 4

3

Dispatcher クラスを使用できます。

Dispatcher.BeginInvoke(
    DispatcherPriority.Input, new Action(() => 
    { 
        //update UI
    }));

Timerただし、あなたの場合、ローカル変数で BackgroundWorker から結果を収集し、ラベルを変更して、WPFオブジェクトに基づいて結果をループします。

于 2012-04-04T22:44:52.137 に答える
1

Dispatcher を使用して GUI を更新できます。これを行う方法のかなり良い例については、このブログ投稿を確認してください。

于 2012-04-04T22:22:28.293 に答える
0

どこで

  txtb_timeline.Text = "should not see this";

結果が得られる場所です。結果は e.Result になり、複数のプロパティで e.Result をパックできます。

中間結果を取得したい場合は、進行状況を使用できます。

于 2012-04-04T22:35:30.977 に答える
0

これらの変更を試してみ
ます: UpdateTimeLine に追加します

 startTimelineUpdater.WorkerReportsProgress = true;
 startTimelineUpdater.ProgressChanged += new ProgressChangedEventHandler
                                      (startTimelineUpdater_ProgressChanged);

startTimelineUpdater_DoWork でこれらの行を削除します

TheTimeLine = sb.ToString();  
_goUpdate += new UpdateTimeLineEvent(MainWindowGoUpdate);  
_goUpdate.Invoke();  

これらを挿入します:

BackgroundWorker bkgwk = sender as BackgroundWorker;
bkgwk.ReportProgress(0, sb.ToString());

最後に進捗イベントを追加します

private void startTimelineUpdater_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
   txtb_timeline.Text = e.ObjectState.ToString();
}

これで、UpdateTimeLine への呼び出しのみを残して、MainWindowGoUpdate メソッドを削除できます。

于 2012-04-04T22:44:12.540 に答える