通常当有人想要执行一些长时间运行的任务并将其进度报告给UI时,在更新UI时,在新线程中调用长时间运行的任务。 我希望做一个更舒适的方法,例如:
MainWindow.SetWatingMsg("please wait ...");
doLongRunnnigTask();
MainWindow.RemoveWaitingMsg();
因此,在这种情况下,应该在与运行长时间运行任务的线程不同的线程中更新UI。 我已经尝试了这个,在我的主窗口中我有一个带有进度条动画的隐藏视图框。在我的应用程序中,我有一个对我的主窗口的引用,所以我的计划是在代码中从不同的地方调用以下函数:
public void SetWaitMsg(string msg)
{
if (Session.User != null)
if (Session.User.Configuration.DontShowWaitMsg)
return;
Task.Factory.StartNew(() =>
{
AppMainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Render, (System.Action)delegate()
{
AppMainWindow.pleaseWaitBox.Visibility = Visibility.Visible;
});
});
}
public void RemoveWaitMsg()
{
Task.Factory.StartNew(() =>
{
AppMainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Render, (System.Action)delegate() { AppMainWindow.pleaseWaitBox.Visibility = Visibility.Collapsed; });
});
}
问题是这不起作用,我没有错误,只是更新。 UI更新的唯一时间是在调用set和删除函数之间打开确认弹出窗口。
帮助将不胜感激。
由于
答案 0 :(得分:0)
最好删除Task.Factory.StartNew()
。但我觉得这不重要。看起来你正在UI线程上执行长时间运行的任务。我的意思是,为了让WPF播放动画,您需要在并行线程上执行操作,同时UI线程将播放您的动画。
因此,此代码用于设置来自任何线程的等待消息:
public void SetWaitMsg(string msg)
{
if (Session.User != null)
if (Session.User.Configuration.DontShowWaitMsg)
return;
AppMainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Render, (System.Action)delegate()
{
AppMainWindow.pleaseWaitBox.Visibility = Visibility.Visible;
});
}
public void RemoveWaitMsg()
{
AppMainWindow.Dispatcher.BeginInvoke(DispatcherPriority.Render, (System.Action)delegate() { AppMainWindow.pleaseWaitBox.Visibility = Visibility.Collapsed; });
}
但是当Yuval帮助我意识到,我们不确定你是否正确地执行了后台任务。因此,假设您在UI线程上执行上面的代码,您的实际代码应如下所示:
MainWindow.SetWatingMsg("please wait ...");
Task.Factory.StartNew(() => doLongRunnnigTask());
MainWindow.RemoveWaitingMsg();
public void SetWaitMsg(string msg)
{
if (Session.User != null && Session.User.Configuration.DontShowWaitMsg)
return;
AppMainWindow.pleaseWaitBox.Visibility = Visibility.Visible;
}
public void RemoveWaitMsg()
{
AppMainWindow.pleaseWaitBox.Visibility = Visibility.Collapsed;
}