您好我正在尝试将另一个具有文本框Arraylist的类中的方法调用到主窗体中的面板中,目前它可以正常工作但是我需要放置方法
我已经尝试了
ThreadStart starter = () => draw.DynamicTextBox(c, f);
Thread thread = new Thread(starter);
thread.Start();
但它给我的对象引用未设置为对象异常的实例或Arraylist为null
//Code in MainForm
public generator draw = new generator();
private void Button1_Click(object sender, EventArgs e)
{
int c = Convert.ToInt16(txbColumn.Text);
int f = Convert.ToInt16(txbRow.Text);
draw.DynamicTextBox(c, f); //needs to be on a Thread
foreach (Control txtb in draw.textboxList)
{
Paneltxb.Controls.Add(txtb);
}
}
//Code in Generator Class
public class generator
{
public ArrayList textboxList;
public void DynamicTextBox(int c, int f )
{
textboxList = new ArrayList();
int n = 0;
for (int x = 0; x < f; x++)
{
for (int y = 0; y < c; y++)
{
n++;
TextBox txtb = new TextBox();
txtb.Text = "txb " + n;
txtb.Name = "txb" + n;
txtb.Location = new Point(y * 100, x * 20);
textboxList.Add(txtb);
}
}
}
}
答案 0 :(得分:3)
它告诉你ArrayList
为null,因为 ArrayList为null 。在那个时间点。
ThreadStart starter = () => draw.DynamicTextBox(c, f);
Thread thread = new Thread(starter);
thread.Start();
// The thread just started running. The textboxes have not been created yet.
// draw.textboxList has not been given a value yet. It's null.
// The stuff in the other thread is happening in a different thread,
// at its own pace.
// The whole point of putting it in another thread is that the rest of the code
// in *this* thread continues executing before the other thread finishes. You can't
// ever make any assumptions about when stuff in another thread happens, unless you
// write code to explicitly synchronize the two, which is a proverbially tricky
// business.
foreach (Control txtb in draw.textboxList)
{
Paneltxb.Controls.Add(txtb);
}
如果你想等到使用另一个线程的结果,直到它完成创建它们,最明显的方法是确保发生这种情况只是在另一个线程中进行。尝试这样的事情:
ThreadStart starter = () => {
draw.DynamicTextBox(c, f);
// We do this Invoke thing because we're messing with UI, which has to
// be done in the UI thread. We're in another thread, so what Invoke
// does for us is it reaches into the UI thread and executes its code
// there. It does this using magic thread runtime pixies or something.
// I don't know what.
this.BeginInvoke(new MethodInvoker(delegate {
foreach (Control txtb in draw.textboxList)
{
Paneltxb.Controls.Add(txtb);
}
});
};
我怀疑,无论如何都会爆炸,因为你正在从UI线程中创建TextBoxes。祝好运。
答案 1 :(得分:0)
你可以尝试async / await(见下文)但是我不确定通过Task.Run()使用新线程是否值得,因为它似乎不需要“并行化”工作:
private async void Button1_Click(object sender, EventArgs e)
{
int c = Convert.ToInt16(txbColumn.Text);
int f = Convert.ToInt16(txbRow.Text);
await Task.Run(()=> draw.DynamicTextBox(c, f));
foreach (Control txtb in draw.textboxList)
{
Paneltxb.Controls.Add(txtb);
}
}
public class generator
{
public ArrayList textboxList;
...
public void DynamicTextBox(int c, int f )
{
...
}...
}
我建议使用async / await模式的一个原因是在访问UI元素时不必担心dipatcher。 await之后的代码将在UI线程上运行,因为await会捕获UI同步上下文。