0

我正在编写一个 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 语句上):

你调用的对象是空的。

为什么它可以从一个按钮工作而不能从另一个按钮工作?以及如何使它从两个按钮都起作用?感谢您的任何回答

编辑:

调用有效的线程

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="对象引用未设置为对象的实例。"
Source="urbar"
StackTrace:
at allin.noveVZ.UlozHlasovanie() in C:\Documents and Settings\ondro\My Documents\Dropbox\urbar\noveVZ.cs:line 485
at allin.noveVZ.b__9() in C:\ Documents and Settings\ondro\My Documents\Dropbox\urbar\noveVZ.cs:line 506
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

4

2 回答 2

0

正如在评论中写LB,datagridview的列是空的。那是我的错误(下面的代码),我通过线程代码将比 ui-thread 代码执行得更快。添加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;
    }
}
于 2012-08-19T21:21:43.697 回答
-1

您正在从另一个线程访问 UI,这是不允许的,尽管我见过它随机工作的情况。您可以通过调用 获取线程中的网格数据Invoke,但为了简单起见,您应该考虑在启动线程之前获取网格数据,并且只在线程中执行 sql 命令,这通常需要更多时间。

于 2012-08-19T07:25:37.847 回答