我正在编写一个C#数据库程序,我想在那里实现一些线程。我在表单上有一个按钮,在那个按钮中我启动了一个线程,它将数据从表单保存到数据库。
效果很好。线程代码:
T1 = new Thread((ThreadStart)delegate
{
UlozHlasovanie();
});
方法代码:
private void UlozHlasovanie()
{
string insert="insert into hlasovanie values (null, (select max(id) from VZ), '"+otazka+"')";
var sql=new SQLiteCommand(insert,spoj);
sql.ExecuteNonQuery();
foreach (DataGridViewRow row in dataGridView2.Rows)//*
{
switch (row.Cells["rozhodnutie"].Value.ToString())
{
case "Za":
insert = "insert into hlasovanierec values (null, " + row.Cells["IDPODDET"].Value + " , (select max(id) from VZ), (select max(id) from hlasovanie), 1)";
break;
case "Proti":
insert = "insert into hlasovanierec values (null, " + row.Cells["IDPODDET"].Value + " , (select max(id) from VZ), (select max(id) from hlasovanie), 2)";
break;
case "Zdrzal sa":
insert = "insert into hlasovanierec values (null, " + row.Cells["IDPODDET"].Value + " , (select max(id) from vZ), (select max(id) from hlasovanie), 3)";
break;
}
sql=new SQLiteCommand(insert,spoj);
sql.ExecuteNonQuery();
}
}
现在的问题。当我从一个按钮调用它时,它完美地工作。但当我从另一个按钮(仍然在同一个窗体上)调用它时,它会抛出这个(在asterix语句中):
未将对象引用设置为对象的实例。
为什么它只能从一个按钮起作用而不能从另一个按钮起作用?以及如何使它从两个按钮工作?感谢ondro的任何答案
编辑:
调用有效的线程
private void button1_Click(object sender, EventArgs e)
{
T1 = new Thread((ThreadStart)delegate
{
UlozHlasovanie();
});
switch (krok)
{
case 1:
...
break;
case 2:
...
break;
...
case 5:
panel1.Visible = false;
panel2.Visible = false;
panel3.Visible = false;
panel4.Visible = false;
panel5.Visible = false;
panel6.Visible = false;
panel7.Visible = true;
T1.Name = "sd";
T1.Start();
//while (!T1.IsAlive);
panel1.Visible = false;
panel2.Visible = false;
panel3.Visible = false;
panel4.Visible = false;
panel5.Visible = false;
panel6.Visible = true;
panel7.Visible = false;
button1.Visible = false;
break;
}
非工作电话:
private void button11_Click(object sender, EventArgs e)
{
T1 = new Thread((ThreadStart)delegate
{
UlozHlasovanie();
});
T1.Name = "asd";
T1.Start();
//while (!T1.IsAlive);
krok = 4;
panel1.Visible = false;
panel2.Visible = false;
panel3.Visible = false;
panel4.Visible = true;
panel5.Visible = false;
panel6.Visible = false;
richTextBox1.Text = "";
foreach (DataGridViewRow row in dataGridView2.Rows)
{
row.Cells["rozhodnutie"].Value = null;
}
}
异常详情:
System.NullReferenceException未处理
Message =“对象引用未设置为对象的实例。”
来源= “urbar”
堆栈跟踪:
atinin.noveVZ.UlozHlasovanie()在C:\ Documents and Settings \ ondro \ My Documents \ Dropbox \ urbar \ noveVZ.cs:line 485
atinin.noveVZ.b__9()在C:\ Documents and Settings \ ondro \ My Documents \ Dropbox \ urbar \ noveVZ.cs:第506行
在System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
在System.Threading.ExecutionContext.Run(ExecutionContext executionContext,ContextCallback回调,对象状态)
在System.Threading.ThreadHelper.ThreadStart()
答案 0 :(得分:0)
在评论中写L.B,datagridview列是null。这是我的错(下面的代码),我通过线程代码将执行更快的ui线程代码。添加while语句将处理此问题,我在线程运行时加载了gif。
private void button11_Click(object sender, EventArgs e)
{
T1 = new Thread((ThreadStart)delegate
{
UlozHlasovanie();
});
T1.Name = "asd";
T1.Start();
while (T1.IsAlive) { Application.DoEvents(); }
krok = 4;
panel1.Visible = false;
panel2.Visible = false;
panel3.Visible = false;
panel4.Visible = true;
panel5.Visible = false;
panel6.Visible = false;
richTextBox1.Text = "";
foreach (DataGridViewRow row in dataGridView2.Rows)
{
row.Cells["rozhodnutie"].Value = null;
}
}
答案 1 :(得分:-1)
你正在从另一个线程访问UI,这是不允许的,虽然我已经看到它是随机工作的情况。您可以通过调用Invoke
来获取线程中的网格数据,但为简单起见,您应该考虑在启动线程之前获取网格数据,并且只在线程中执行通常需要更多时间的sql命令。