我想了解如何定期使用简单的文本字符串更新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";
}
}
答案 0 :(得分:2)
您可以使用Dispatcher类:
Dispatcher.BeginInvoke(
DispatcherPriority.Input, new Action(() =>
{
//update UI
}));
但是在我的情况下,我会在局部变量中从BackgroundWorker收集结果,然后根据WPF Timer
对象更改标签以循环显示结果。
答案 1 :(得分:1)
您可以使用Dispatcher更新GUI。请查看this blog post以获取有关如何操作的相当好的示例。
答案 2 :(得分:0)
你在哪里
txtb_timeline.Text = "should not see this";
是获得结果的地方。结果将在e.Result中 您可以使用多个属性打包e.Result。
如果您想获得中间结果,可以使用进度。
答案 3 :(得分: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方法