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();
    }
}

我的大部分问题都在上面的评论中,但这里列出了它们:

  1. 由于某种原因,uiUpdate 似乎为空...如果我做错了,如何获得调度程序?(w线程.cs问题(

    uiUpdate = Program.myForm.dispat'
    
  2. 有没有办法将字符串传递到上面,以便更新标签起作用?

    Action myDelegate = new Action(updateLabel);
    
  3. 我希望下面的行可以工作

    uiUpdate.BeginInvoke(new Action(delegate() { Program.myForm.label1.Text = "count at " + i; }));
    
  4. 也希望我能做下面的注释代码

    uiUpdate.Invoke(myDelegate)
    

编辑:我将 wThread 构造函数 wThread worker = new wThread(( 移出了 form1 初始化区域...它修复了我的空指针。相反,我将 wThread 构造函数移动到构造表单的静态主空隙中......像Application.Run(myForm(;

不幸的是,在我关闭UI之前,wThread不会启动。最好的办法是什么?在 Application.Run 启动我的表单之前创建另一个线程并使用该线程启动我的真实线程?

NullReferenceException @ Dispatcher & Other GUI Issues

@1:在构造函数Form1,在dispat = Dispatcher.CurrentDispatcher;放置一个断点并检查值是什么。可能只是Dispatcher.CurrentDispatcher为空,您必须稍后获取它,而不是在 ctor 中

@2 是的。使用Func<string>而不是操作。InvokeBeginInvoke 接受一个委托,以及一组构成委托调用参数的params object[]。当然,传递的参数数组必须与委托签名完全匹配,因此在使用时Func<string>只使用一个项目的对象[]:字符串。

@3 - 是的,只要i是可以通过委托闭包捕获的简单局部变量,就可以工作。如果它是迭代器或一些非本地成员foreach则可能会有问题,但是,好吧,不同的故事。

@4 - 是的,它会起作用,只要记住也为Func<string>传递参数。