c#空引用异常
本文关键字:异常 引用 | 更新日期: 2023-09-27 18:18:48
我正在编写下面这个处理线程和线程优先级的程序。
我已经构造了一个windows窗体包含一个丰富的文本框(DisplayTextBox)和两个按钮(StartButton用于运行应用程序和ExitButton用于关闭应用程序)。
在表单中,我创建了几个线程并一个接一个地运行它们。每个线程使用的方法在Threading类中找到。这个方法是PrintOnScreen()。
在这个方法中,我将线程名称及其优先级附加到StringBuilder类型的str。然后我想在DisplayTextBox中显示str的内容(在Form.cs中)。
然而,我得到一个"NullReferenceException未处理:对象引用未设置为对象的实例"错误。出现错误的行如下:
DisplayTextBox。
你能帮我解决这个错误吗?谢谢。
编辑
谢谢大家的帮助。为了解决这个问题,我将PrintOnScreen方法复制到Form.cs类中,并丢弃Threading.cs。
我后来使用了Anand给出的代码,并把它放在t2.Join()下面。
问题发生在表单的构造函数中。再次将DisplayText
声明为本地成员,这样表单的字段就不会初始化。像这样修改构造函数:
private void Form1_Load(object sender, EventArgs e)
{
DescTextBox.Visible = false;
DisplayTextBox = new RichTextBox();
DisplayTextBox.Location = new Point(15, 31);
DisplayTextBox.Height = 258;
DisplayTextBox.Width = 303;
panel1.Controls.Add(DisplayTextBox);
}
,它应该像你期望的那样工作。
Edit:但是当你想从后台工作线程更改UI元素时,要注意你会遇到的问题。在这些情况下,您将不得不使用调用模式。
我在简单的控制台应用程序中尝试了这个,它工作得很好。问题在于DisplayTextBox。如果你想与任何控件交互,那么你必须使用UI线程或Dispatcher。在Threading类中使用以下代码:而不是
DisplayTextBox.Text = Convert.ToString(str);
用这个
Dispatcher.Invoke(DispatcherPriority.Normal,
new Action(
delegate()
{
DisplayTextBox.Text = Convert.ToString(str);
}
));
您不能与主应用程序线程以外的任何线程的控件通信。你需要使用调色器。看看这里:http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcher.aspx
编辑
@Fischermaen -嘿,没有注意到这个,但是它仍然不能工作,因为他写的那一行失败了。他仍然需要使用分派器从非主线程
编辑2
相关的线程:
如何从c#中的另一个线程更新GUI ?
在WinForms中,为什么不能从其他线程更新UI控件?
从这里看不出来,但是你遇到困难的部分原因是你的代码缺乏封装和糟糕的生命周期管理。
在PrintOnScreen方法中实例化str,并给它起一个更好的名字,显然不需要是成员变量,也不需要将其设为public。
不返回void结果,而是返回字符串result
。
SomeTextBox = PrintOnScreen(); // (GetThreadDetails might be a better name...)
作为一个提示,不要把表示和逻辑混在一起。让你的UI控件完全属于拥有它们的人。
和不做
public SomeType SomeName;
使它成为一个属性并给它一个getter和setter,即使它是缩写形式
public SomeType someename {get;设置;}
任何其他代码位都可能做一些非常愚蠢的事情,比如
Form1.SomeType = (SomeOtherType)someVar; // with appaling consequences.
任何东西都应该有一个以上的所有者,否则将导致毁灭。
PS str. tostring()是比Convert.ToString(str)更好的选择;
嗯,这对我来说不是很清楚你想要实现什么,但问题是,当你试图访问控制它(窗口句柄仍然不存在)时,基本形式Threading类继承自未加载,这也是你在Form1本身看不到任何东西的原因,因为你的线程输出到隐藏的形式,这是不显示的。
我认为你正在试图解决线程访问问题,由SOReader提出。这样做是不对的