我有一个控制台应用程序,它在另一个线程中启动一个表单应用程序(来自另一个类)。
但是,我不想在主线程中从我的主类访问richTextBox1
组件,并且会抛出一个错误,说我试图从另一个组件访问该组件线程。
我的代码: (表格申请)
public partial class ChatGui : Form
{
public static RichTextBox textBox;
public ChatGui()
{
InitializeComponent();
richTextBox1.ReadOnly = true;
richTextBox1.BackColor = SystemColors.Window;
}
public void WriteLine(string line)
{
richTextBox1.Text += line+"\r\n";
}
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
WriteLine("[You]: "+textBox1.Text);
NetworkManager.SendPacket("rchat_msg " + textBox1.Text.Replace(" ", "%20"));
textBox1.Text = "";
e.Handled = true;
}
}
public void Exit()
{
Application.Exit();
}
private void ChatGui_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = true;
}
}
主控台应用程序
public static void StartRemoteChat()
{
RemoteChat = true;
Program.ChatGui = new ChatGui();
new Thread(new ThreadStart(() =>
{
Application.Run(Program.ChatGui);
while (RemoteChat)
{
// ...
}
})).Start();
}
那么,如何在不发生此错误的情况下从主线程中访问richTextBox1
组件(我想更改组件的某些变量)?
答案 0 :(得分:3)
该控件由创建它的线程拥有。
在你的情况下,你开始的线程拥有表单,因为它绘制它,因此它将成为你的表单ui线程。
但是,当您尝试使用另一个线程对控件进行更改时,它将像您所说的那样抛出异常。
解决这个问题的方法是调用创建它的线程来进行所需的更改:
var reverseObj = function(object) {
var NewObj = {}, keysArr = Object.keys(object);
for (var i = keysArr.length-1; i >= 0; i--) {
NewObj[keysArr[i]] = object[keysArr[i]];
}
return NewObj;
}
答案 1 :(得分:0)
可以帮助你的是“CheckForIllegalCrossThreadCalls = false;”但在这里使用(开头):
public Form1()
{
InitializeComponent();
CheckForIllegalCrossThreadCalls = false;
}
建议是使用每次调用“RichTextBox1”的invoke方法。 此方法允许与其他线程创建的元素进行交互。 例如:
richTextBox1.Invoke(new Action(() => richTextBox1.Text = "hello word"));
“CheckForIllegalCrossThreadCalls = false”是一种在复杂程序中使用时具有足够危险的解决方案。 我希望我能提供帮助。
答案 2 :(得分:0)
简单的调用调用从新线程调用该方法:
if (InvokeRequired)
{
Invoke(new Action(**METHODHERE**));
return;
}
并传递参数:
if (InvokeRequired)
{
Invoke(new Action<string>(**METHODHERE**) **parameter**);
return;
}
好读:https://msdn.microsoft.com/en-us/library/ms171728(v=vs.110).aspx
答案 3 :(得分:-2)
尝试设置以下属性。
RichTextBox.CheckForIllegalCrossThreadCalls=false;
这可能会对你有帮助。