我有一个名为“findListText”的文本块。在这里,我正在更新其中的文字:
private void InstantSearch(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
HitEnter = true;
}
findListText.Text = "Processing request. Please wait...";
Find(bool.Parse("False" as string));
}
但是,下一组代码是一个搜索函数,最多可能需要10秒,在它结束时,它会再次更改findListText中的文本。
private void Find(bool? bForward = true)
{
{
//Lots and lots of code
}
findListText.Text = "Search completed."
}
问题是,文本块似乎永远不会更新为“处理请求。请稍候......”。文本块处于原始状态,10秒后更新为“搜索完成。”,似乎正在跳过中间人。
我正在使用C# - WPF。我在这里做错了什么?
答案 0 :(得分:3)
无论我认为什么技术都无所谓。
代码在同一个线程上运行,这意味着UI不会被更新,直到该线程上的所有代码都完成。您应该使用不同的线程来更新该文本块。
在这种情况下,你将有2个帖子:
我已经创建了a little something来解决您的问题,它基于this Stack Overflow页面
答案 1 :(得分:1)
您应该研究WPF的UI线程概念。调用Dispatcher
修改文本框。此外,搜索应与ThreadPool.QueueWorkerItem
一起运行。
// Start worker thread
ThreadPool.QueueUserWorkItem(state =>
{
// Long running logic here
findListText.Dispatcher.BeginInvoke(() => findListText.Text = "Processing request. Please wait...");
Find(bool.Parse("False" as string));
// Tip: Run change on GUI thread from the worker using the dispatcher
findListText.Dispatcher.BeginInvoke(() => findListText.Text = "Search completed.");
});
答案 2 :(得分:1)
由于这是WPF,请尝试以下操作:将文本更改为“Processgin”后,请调用:
Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, new Action(delegate { this.UpdateLayout(); }));
这将告诉线程尽快更新UI。
答案 3 :(得分:1)
以下是如何在自己的线程中运行find方法。
private void InstantSearch(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
HitEnter = true;
}
findListText.Text = "Processing request. Please wait...";
BackgroundWorker tempWorker = new BackgroundWorker();
tempWorker.DoWork += delegate
{
Find(bool.Parse("False" as string));
};
tempWorker.RunWorkerAsync();
}
如果您尝试这样做,您将收到错误,因为您从后台线程访问您的UI线程。因此,您还需要更新find方法。
private void Find(bool? bForward = true)
{
{
//Lots and lots of code
}
Dispatcher.BeginInvoke((Action) delegate {
findListText.Text = "Search completed."
});
}
答案 4 :(得分:0)
我刚刚回到这里,并在互联网上浏览了类似的问题。对于像在长时间运行的进程发生之前推送单个消息这样简单的事情,我很惊讶没有人建议“Application.DoEvents();”。是的,我知道它有它的缺点,我的UI仍然会挂起,但这至少适合我的情况。