C# c线程,无法调用调用
几天前我启动了c,所以有些事情与java完全不同,几天前我遇到了一个问题,关于一个线程更改UI,将行添加到DataGridView,我发现我必须调用方法Invoke来实现这一点。我做到了,一切正常,但现在我面临一个新问题。因此,我有一个框架,将显示一些动态添加的标签,在Java中,我希望这样:C# c线程,无法调用调用,c#,multithreading,invoke,C#,Multithreading,Invoke,几天前我启动了c,所以有些事情与java完全不同,几天前我遇到了一个问题,关于一个线程更改UI,将行添加到DataGridView,我发现我必须调用方法Invoke来实现这一点。我做到了,一切正常,但现在我面临一个新问题。因此,我有一个框架,将显示一些动态添加的标签,在Java中,我希望这样: Thread t = new Thread() { public void run() { while (true) { // f
Thread t = new Thread() {
public void run() {
while (true) {
// for each label
for (it = labels.iterator(); it.hasNext();) {
JLabel lb = it.next();
if (lb.getLocation().x + lb.getWidth() < 0) {
if (msgsRemover.contains(lb.getText().toString())) {
it.remove();
MyPanel.this.remove(lb);
msgsRemover.remove(lb.getText().toString());
} else {
// if there is no message to be removed, this will just continue
// going to the end of the queue
MyPanel.this.remove(lb);
MyPanel.this.add(lb);
}
MyPanel.this.repaint();
MyPanel.this.validate();
}
lb.setLocation(lb.getLocation().x - 3, 0);
}
MyPanel.this.repaint();
try {
SwingUtilities.invokeAndWait(running);
sleep(30);
} catch (InterruptedException ex) {
Logger.getLogger(MyPanel.class.getName()).log(Level.SEVERE, null, ex);
} catch (InvocationTargetException ex) {
Logger.getLogger(MyPanel.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
};
所以我做了:
if (lb.Location.X + lb.Width < 0) {
if (msgsRemover.Contains(lb.Text.ToString())) {
labels.Remove(label);
this.Invoke(new MethodInvoker(() => { this.Controls.Remove(lb); }));
msgsRemover.Remove(lb.Text.ToString());
} else {
// if there is no message to be removed, this will just continue
// going to the end of the queue
this.Invoke(new MethodInvoker(() => { this.Controls.Remove(lb); }));
this.Invoke(new MethodInvoker(() => { this.Controls.Add(lb); }));
}
this.Invoke(new MethodInvoker(() => { this.Refresh(); }));
但是要知道,在创建窗口句柄之前,我会收到一个名为Can not call Invoke或BeginInvoke的错误。
我一直在寻找解决方案,但我没有找到我能做些什么来解决这个问题。
提前感谢您的帮助
编辑:启动线程是我在构造函数中做的最后一件事。。。代码如下:
public MyPanel(Color corLabel, Color back, Font text){
this.color = corLabel;
this.backg = back;
this.textFont = text;
this.Width = 500000;
texto = new LinkedList<string>();
msgs = new LinkedList<MensagemParaEcra>();
labels = new LinkedList<Label>();
var it = labels.GetEnumerator();
var it2 = msgsRemover.GetEnumerator();
this.FlowDirection = FlowDirection.LeftToRight;
this.BackColor = backg;
this.Size = new Size(500000, 30);
this.Refresh();
startThread();
}
您收到的错误表明目标窗口尚未完全创建。可能构造器还没有完成。尝试连接到目标窗口的一个默认事件加载、显示等,并在处理这些事件后进行调用。您收到的错误表明目标窗口尚未完全创建。可能构造器还没有完成。尝试连接到目标窗口的一个默认事件Load、Show等,并在处理这些事件后进行调用。必须在控件创建句柄后启动线程才能进行调用,最简单的方法是重写该方法并在那里启动线程
public MyPanel(Color corLabel, Color back, Font text)
{
this.color = corLabel;
this.backg = back;
this.textFont = text;
this.Width = 500000;
texto = new LinkedList<string>();
msgs = new LinkedList<MensagemParaEcra>();
labels = new LinkedList<Label>();
var it = labels.GetEnumerator();
var it2 = msgsRemover.GetEnumerator();
this.FlowDirection = FlowDirection.LeftToRight;
this.BackColor = backg;
this.Size = new Size(500000, 30);
this.Refresh();
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
startThread();
}
您必须在控件创建句柄后启动线程,以便能够进行调用,最简单的方法是重写该方法并在那里启动线程
public MyPanel(Color corLabel, Color back, Font text)
{
this.color = corLabel;
this.backg = back;
this.textFont = text;
this.Width = 500000;
texto = new LinkedList<string>();
msgs = new LinkedList<MensagemParaEcra>();
labels = new LinkedList<Label>();
var it = labels.GetEnumerator();
var it2 = msgsRemover.GetEnumerator();
this.FlowDirection = FlowDirection.LeftToRight;
this.BackColor = backg;
this.Size = new Size(500000, 30);
this.Refresh();
}
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
startThread();
}
启动线程是我在构造函数中做的最后一件事。。。我将用构造函数编辑我的问题开始一个线程是我在构造函数中做的最后一件事。。。我将使用构造函数编辑我的问题,但不要在工作线程上创建控件。你在要求痛苦。如果您必须在涉及UI控件的工作线程上执行任何操作,请确保操作简单。您在这里拥有的甚至都不接近。不要在工作线程上创建控件。你在要求痛苦。如果您必须在涉及UI控件的工作线程上执行任何操作,请确保操作简单。这里的内容还没有结束。谢谢,我创建了一个公共方法来调用startThread,现在它可以工作了,非常感谢!谢谢,我创建了一个公共方法来调用startThread,现在它可以工作了,非常感谢!