[英]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.