调度员.调用方法有时不工作
本文关键字:工作 调用 方法 调度员 | 更新日期: 2023-09-27 18:18:44
我在使用调度程序时遇到了一个非常奇怪的问题。在wpf中调用方法
背景:我定义了一个用户控件,有一个DoWorkEventArgs来支持一些异步工作:
public class MyUserControl : UserControl
{
private BackgroundWorker bw;
public MyUserControl()
{
bw.DoWork += new DoWorkEventHandler(DoWorkMethod);
}
public void StartWork()
{
bw.RunWorkerAsync();
}
void DoWorkMethod(object sender, DoWorkEventArgs e)
{
this.Dispatcher.Invoke((System.Action)delegate()
{
//Add some item in a ListBox, this ListBox is defined in the user control.
TextBlock b = new TextBlock();
//some code
Listbox.Items.Add(b);
}
}
}
当一个按钮点击时,我创建了这个用户控件的2个实例,并调用那里的StartWork方法:
MyUserControl control1 = new MyUserControl();
MyUserControl control2 = new MyUserControl();
control1.StartWork();
control2.StartWork();
这就是问题所在,有时usercontrol1中的ListBox没有更新,其中没有项目,有时这种情况发生在usercontrol2的ListBox中,我调试它们,发现代码运行正常,ListBox. items . add方法运行,结果只是不出来。如果我改变Dispatcher。给调度员开发票。BeginInvoke,那么它是正常的。有人知道原因吗?
首先,你使用的BackgroundWorker
是无效的,因为你试图在UI线程上运行DowWork
方法,但该方法的整个目的是它在后台线程上运行。如果您想知道如何正确实现BackgroundWorker
,那么请参阅我对如何正确实现具有ProgressBar更新的BackgroundWorker的回答?关于Stack Overflow的问题
然而,如果你只是想异步运行一些代码,你真的不需要使用BackgroundWorker
这些天。相反,您可以使用Task
类做这样的事情:
Task.Factory.StartNew(() => NameOfMethodToRunAsynchronously);
如果你需要在UI线程上运行NameOfMethodToRunAsynchronously
方法的一部分,那么你可以返回到Dispatcher.Invoke
调用:
private void NameOfMethodToRunAsynchronously()
{
// Some long running process
Dispatcher.Invoke((System.Action)delegate()
{
//Add some item in a ListBox, this ListBox is defined in the user control.
TextBlock b = new TextBlock();
//some code
Listbox.Items.Add(b);
}
}
最后,为了回答您最初对Dispatcher
类的担忧,请参阅MSDN上的Dispatcher
类页面。从那一页:
为线程提供管理工作项队列的服务。
注意这里说的是一个线程,而不是UI线程。这意味着它可以是你想要的UI线程,但不一定。为了确保它将用于UI线程,我们可以简单地在MainWindow.xaml.cs
的构造函数中将其设置在UI线程上:
Dispatcher uiDispatcher = Application.CurrentDispatcher;
所以要确保你的Dispatcher
将在UI线程上运行,只需使用该实例:
uiDispatcher.Invoke((System.Action)delegate()
{
//Add some item in a ListBox, this ListBox is defined in the user control.
TextBlock b = new TextBlock();
//some code
Listbox.Items.Add(b);
}