前回の記事を書いたときに、ふと表題の件が気になっていた。
DataGridViewのDataSourceに指定したDataTableを別スレッドから更新するとどうなるのだろうか?
早速実験してみることにした。
まず前回のコードを再掲する。
Form1.cs
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Data.SQLite; namespace SqliteLesson { public partial class Form1 : Form { public Form1() { InitializeComponent(); } /// <summary> /// テーブルの作成とデータ追加 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button1_Click(object sender, EventArgs e) { using (SQLiteConnection con = new SQLiteConnection("Data Source=sqlitelesson.db")) using (SQLiteCommand cmd = con.CreateCommand()) { con.Open(); // テーブル作成 cmd.CommandText = "CREATE TABLE Lesson (ID INTEGER PRIMARY KEY, Name NVARCHAR(128), Age INTEGER)"; cmd.ExecuteNonQuery(); // データ追加 cmd.CommandText = "INSERT INTO Lesson (Name,Age) VALUES('Tom',43)"; cmd.ExecuteNonQuery(); cmd.CommandText = "INSERT INTO Lesson (Name,Age) VALUES('John',29)"; cmd.ExecuteNonQuery(); cmd.CommandText = "INSERT INTO Lesson (Name,Age) VALUES('Mike',35)"; cmd.ExecuteNonQuery(); } } private DataTable dataTable = new DataTable(); protected override void OnLoad(EventArgs e) { dataGridView1.DataSource = dataTable; base.OnLoad(e); } /// <summary> /// テーブルの内容を表示 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { using (SQLiteConnection con = new SQLiteConnection("Data Source=sqlitelesson.db")) using (SQLiteDataAdapter adapter = new SQLiteDataAdapter("SELECT * FROM Lesson", con)) { adapter.Fill(dataTable); } } } }
今回は実験のため62行目から69行目の部分を以下のように書き換えた。
/// <summary> /// テーブルの内容を表示 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void button2_Click(object sender, EventArgs e) { new System.Threading.Thread(new System.Threading.ThreadStart(() => { using (SQLiteConnection con = new SQLiteConnection("Data Source=sqlitelesson.db")) using (SQLiteDataAdapter adapter = new SQLiteDataAdapter("SELECT * FROM Lesson", con)) { adapter.Fill(dataTable); } })).Start(); }
このようにして、DataTableの更新を別スレッドから実行するようにした。
さて、実行結果はというと、
何も表示されなかった。。。
デバッガで追ってみた限りでは確かに上のロジックは実行されているし、
テーブルにもデータは入っているようだった。
確信が持てた訳では無いのだが、DataSourceを別スレッドから更新するとUI側でうまく表示できないのかも知れない。