[英]Update GUI from background worker or event
我想了解如何使用簡單的文本字符串定期更新我的 GUI。 本質上,我正在編寫一個 twitter 應用程序,它定期輪詢 twitter 以獲取更新。 我希望更新的內容顯示在一個文本塊中,一個一個地循環顯示。
為了保持 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";
}
}
您可以使用調度員 class:
Dispatcher.BeginInvoke(
DispatcherPriority.Input, new Action(() =>
{
//update UI
}));
但是,在您的情況下,我會在局部變量中收集來自 BackgroundWorker 的結果,然后更改您的 label 以基於 WPF Timer
object 循環遍歷結果。
您可以使用 Dispatcher 來更新您的 GUI。 查看此博客文章以獲得有關如何執行此操作的一個很好的示例。
你在哪里
txtb_timeline.Text = "should not see this";
是您獲得結果的地方。 結果將在 e.Result 中,您可以將 e.Result 與多個屬性打包在一起。
如果你想獲得中間結果,你可以使用進度。
我會嘗試這些改變:
在您的 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 方法
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.