【WPF】別スレッドでSQLiteのDBを検索、画面に表示するには?

プログラミングTips
この記事は約4分で読めます。

自作プログラムでデータベースを検索する場合、特に何も考慮しなければ結果が返ってくるまで画面がフリーズしてしまいます。

検索中も画面を操作したい場合や、検索途中で強制中断したい場合などは、検索処理を別スレッドで実行することになりますが、別スレッドで得た検索結果をそのまま画面に表示しようとすると、エラーが発生してしまいます。

今回は、SQLiteのデータベースに対して別スレッドで検索し、検索結果をDataGridに表示するという一連の流れについて解説したいと思います。

やりたいこと

「データやファイルの読み込み中であっても、画面がフリーズすることなく操作ができるようにしたい」ということが目標です。

今回紹介するサンプルプログラムのは、「SQLiteに対して検索を行っている間、画面がフリーズすることなく、中止ボタンを押すことで検索処理を中断できる」といったものです。

実現方法

画面の「検索ボタン」のクリックイベントにて、SQLiteへの検索処理を別スレッドで実行します。

呼び出した画面側では、スレッドの終了を待たないようにすることで、検索中であっても画面操作が可能になります。

とまあ、ここまでは簡単なのですが、ひとつ考慮する点があって、別スレッドの検索が完了ことを画面側に知らせる必要があります。

これは、検索処理が完了した時点でイベントを発生させるようにすれば解決します。

画面側では、そのイベントを受取り、コントロールに検索結果をセットすればOKです。

別スレッドからコントロールにアクセスする

ただし注意点があって、別タスクの検索結果をそのままコントロールにセットすると、下記のエラーが発生します。

これは、別スレッドの中から画面のコントロールにアクセスできない」という制限があるためです。

イベントハンドラに記述した処理は別スレッドから呼び出されるので、結果的に上記の制限に引っかかってエラーが発生します。

このエラー回避の回避策として、 this.Dispatcher.Invoke を使って次のように記述する方法があります。

サンプルプログラムでは、この方法を使って別スレッドの中から画面のコントロールに検索結果をセットしています。

サンプルプログラムのソースコード

サンプルプログラムの概要

今回紹介するサンプルプログラムは次の様な構成になっています。

SQLiteLibには、SQLiteに対してSQLを実行したり、結果を受取ったりするメソッドが入っています。

TaskCompletedEventArgsは、SQLiteLibの検索メソッドで取得したデータ(検索結果はDataTableに格納)を、呼び出し元(MainWindow.xaml.cs)に返すためのクラスです。

サンプル プログラムのダウンロードURL

ソースコードはこちらからダウンロードできます。

尚、SQLiteのライブラリは含んでいませんので、ビルド&実行したい場合は、NuGetからパッケージをインストールして下さい。

インストール方法の詳細についてお知りになりたい方は、こちらの記事をどうぞ。

ソースコードの紹介

まず最初にMainWindow.xamlです。

次に、 MainWindow.xaml.cs です。

最後に、SQLiteLibとTaskCompletedEventArgs のクラスです。

まとめ

今回は、WPFの画面から別タスクでデータベースに検索を行い、結果を画面に表示するという一連の流れについて紹介いたしました。

題材はデータベース検索ですが、ここで紹介した方法はCSVの読み書きやデータの入力待ちなど、時間の掛かる処理を行わせた時に、画面をフリーズさせたくない場合に使える方法です。

サンプルプログラムは必要最小限の機能しかなく、例えば「検索」ボタンを押してから検索が終わるまで「検索」ボタンの色を変えておくとか、処理完了メッセージを表示するとかは行っていません。

これを参考にするか、あるいはカスタマイズしてお役立ていただければと思います。

この記事が皆様のプログラミングの一助になれば幸いです。

タイトルとURLをコピーしました