线程从一个按钮成功但不从另一个按钮成功

时间:2012-08-19 07:15:18

标签: c# sql multithreading sqlite

我正在编写一个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()

2 个答案:

答案 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命令。