NullReferenceException @ Dispatcher & Other GUI Issues
本文关键字:Other GUI Issues amp Dispatcher NullReferenceException | 更新日期: 2023-09-27 18:33:51
我一直在尝试实现多类线程 GUI 管理。如 In 我希望不同的线程分布在不同.cs文件中的多个类中,以根据需要更新 UI。
我搜索了stackoverflow和其他来源,发现大多数人使用Dispatcher.Invoke或类似的东西。所以我决定开始测试...
下面是一个名为 wThread.cs 的类中的线程,
public class wThread
{
public EventHandler SignalLabelUpdate;
public Dispatcher uiUpdate;
public wThread()
{
uiUpdate = Program.myForm.dispat;
//the uiUpdate seems to be null for some reason... If i am doing it wrong how do i get the dispatcher?
Thread myThread = new Thread(run);
myThread.Start();
}
Action myDelegate = new Action(updateLabel);
// is there a way i can pass a string into the above so updatelabel will work?
public void updateLabel(String text)
{
if (SignalLabelUpdate != null)
SignalLabelUpdate(this, new TextChangedEvent(text));
}
public void run()
{
while (uiUpdate == null)
Thread.Sleep(500);
for (int i = 0; i < 1000; i++)
{
//I hope that the line below would work
uiUpdate.BeginInvoke(new Action(delegate() { Program.myForm.label1.Text = "count at " + i; }));
// was also hoping i can do the below commented code
// uiUpdate.Invoke(myDelegate)
Thread.Sleep(1000);
}
}
}
下面是我的form1.cs它是Visual Studio 2012的预加载代码,
public partial class Form1 : Form
{
public Dispatcher dispat;
public Form1()
{
dispat = Dispatcher.CurrentDispatcher;
InitializeComponent();
wThread worker = new wThread();
}
}
我的大部分问题都在上面的评论中,但这里列出了它们:
由于某种原因,uiUpdate 似乎为空...如果我做错了,如何获得调度程序?(w线程.cs问题(
uiUpdate = Program.myForm.dispat'
有没有办法将字符串传递到上面,以便更新标签起作用?
Action myDelegate = new Action(updateLabel);
我希望下面的行可以工作
uiUpdate.BeginInvoke(new Action(delegate() { Program.myForm.label1.Text = "count at " + i; }));
也希望我能做下面的注释代码
uiUpdate.Invoke(myDelegate)
编辑:我将 wThread 构造函数 wThread worker = new wThread(( 移出了 form1 初始化区域...它修复了我的空指针。相反,我将 wThread 构造函数移动到构造表单的静态主空隙中......像Application.Run(myForm(;
不幸的是,在我关闭UI之前,wThread不会启动。最好的办法是什么?在 Application.Run 启动我的表单之前创建另一个线程并使用该线程启动我的真实线程?
@1:在构造函数Form1
,在dispat = Dispatcher.CurrentDispatcher;
放置一个断点并检查值是什么。可能只是Dispatcher.CurrentDispatcher
为空,您必须稍后获取它,而不是在 ctor 中
@2 是的。使用Func<string>
而不是操作。Invoke
和 BeginInvoke
接受一个委托,以及一组构成委托调用参数的params object[]
。当然,传递的参数数组必须与委托签名完全匹配,因此在使用时Func<string>
只使用一个项目的对象[]:字符串。
@3 - 是的,只要i
是可以通过委托闭包捕获的简单局部变量,就可以工作。如果它是迭代器或一些非本地成员foreach
则可能会有问题,但是,好吧,不同的故事。
@4 - 是的,它会起作用,只要记住也为Func<string>
传递参数。