我在WPF最近已经开始规划并撞到了以下问题。 我不明白如何使用Dispatcher.Invoke()
方法。 我在线程经验,我已经做了几个简单的Windows窗体,我只是使用的程序
Control.CheckForIllegalCrossThreadCalls = false;
是的,我知道这是很蹩脚的,但这些都是简单的监控应用。
事实是,现在我想提出一个WPF应用程序在后台检索数据,我开始了一个新的线程进行调用来检索(从网络服务器)的数据,现在我要显示它在我的WPF形式。 关键是,我不能设置从这个线程任何控制。 甚至没有标签或任何东西。 这又如何解决?
答评论:
@Jalfp:
所以我用这个方法调度员在“新胎”时,我得到的数据? 或者我应该做一个后台工作检索数据,把它放入一个领域,并开始一个新的线程等待直到这个字段被填充,并调用调度显示检索到的数据进入控制?
的第一件事就是了解,分派没有设计运行长阻塞操作(比如从网络服务器检索数据...)。 当你想运行将在UI线程上执行的操作(如更新进度条的值),可以使用调度。
你可以做的是在后台工作,以检索您的数据,并使用ReportProgress方法来传播在UI线程中的变化。
如果确实需要直接使用分派器,这是很简单的:
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(() => this.progressBar.Value = 50));
JAPF有正确的回答。 以防万一,如果你正在寻找的多线操作,您可以按照以下写。
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(() => {
this.progressBar.Value = 50;
}));
谁想要了解性能的其他用户的信息:
如果你的代码需要高性能的写入,可以先检查是否使用的checkAccess标志所需的调用。
if(Application.Current.Dispatcher.CheckAccess())
{
this.progressBar.Value = 50;
}
else
{
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background,
new Action(() => {
this.progressBar.Value = 50;
}));
}
需要注意的是方法CheckAccess()是从Visual Studio 2015年隐藏所以只写它不期待的智能感知,以显示它。 需要注意的是的checkAccess对性能开销(开销在几纳秒)。 当你想保存到不惜任何代价进行“调用”要求微秒它只有更好。 此外,总有选项来创建两个方法(与调用,以及其他没有)时调用的方法是知道这是否是在UI线程与否。 这只是最稀有罕见的情况时,你应该寻找在调度员的这一方面。
当一个线程执行,并要执行这是由当前线程阻塞主UI线程,然后使用下面:
当前线程:
Dispatcher.CurrentDispatcher.Invoke(MethodName,
new object[] { parameter1, parameter2 }); // if passing 2 parameters to method.
主UI线程:
Application.Current.Dispatcher.BeginInvoke(
DispatcherPriority.Background, new Action(() => MethodName(parameter)));