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();
        }              
    }

今質問です。1 つのボタンから呼び出すと、完全に機能します。しかし、別のボタン(まだ同じフォームにあります)から呼び出すと、これがスローされます(アスタリスクステートメントで):

オブジェクト参照がオブジェクト インスタンスに設定されていません。

あるボタンからは機能し、別のボタンからは機能しないのはなぜですか? 両方のボタンから機能させる方法は?オンドロに答えてくれてありがとう

編集:

動作するスレッドの呼び出し

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:
C:\Documents and Settings\ondro\My Documents\Dropbox\urbar\noveVZ.cs:
の allin.noveVZ.UlozHlasovanie(): 485 行目 C:\ の allin.noveVZ.b__9() Documents and Settings\ondro\My Documents\Dropbox\urbar\noveVZ.cs:
System.Threading.ThreadHelper.ThreadStart_Context(オブジェクト状態)
の 506 行目 System.Threading.ExecutionContext.Run(ExecutionContext executionContext、ContextCallback コールバック、オブジェクト状態)
でSystem.Threading.ThreadHelper.ThreadStart()

4

2 に答える 2

0

コメントで書いたLBのように、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;
    }
}
于 2012-08-19T21:21:43.697 に答える
-1

別のスレッドからUIにアクセスしており、これは許可されていませんが、ランダムに機能する場合があります。を呼び出すことInvokeでスレッド内のグリッドデータを取得できますが、ここでは簡単にするために、スレッドを開始する前にグリッドデータを取得することを検討し、通常は時間がかかるスレッドでsqlコマンドのみを実行する必要があります。

于 2012-08-19T07:25:37.847 に答える