■はじめに
前回のプログラムは大きなCSVを読み込むと、読み込み完了までの間、画面が固まってしまいます。
そこで今回はその対策をします。
キーワード:TaskbarItemInfo, async, await, ドキュメントアウトライン
[注意]
これまでの回で説明済みの操作方法等は、説明を省略したり簡略化している場合があります。
■開発環境
- Windows 10 (バージョン1703)
- Visual Studio Community 2017
- .NET Framework 4.x
■作ってみる
◇処理中テキスト
ドキュメントアウトラインでlistView
の目のアイコンをクリックしてリストビューを非表示にします。
TextBlock
をリストビューのあったグリッド行(Row=1)に配置します。
TextBlock
を右クリック、「レイアウト」 - 「すべてリセット」し、
x:Name
をloadingText
にし、
プロパティの
「レイアウト」 - HorizontalAlignment
とVerticalAlignment
をCenter
に、
「テキスト」のFontSize
を48 px
に、
「共通」のText
を読み込み中・・・
に設定します。
TextBlock
のプロパティ「外観」のVisibility
をCollapsed
にして非表示にします。
TextBlock
の設定が終わったので、ドキュメントアウトラインでlistView
の非表示を解除しておきます。
ここまででTextBlock
の定義は以下のようになっています。
<TextBlock x:Name="loadingText" Grid.Row="1" TextWrapping="Wrap" Text="読み込み中・・・" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="48" Visibility="Collapsed"/>
◇処理中タスクバー
MainWindow
にタスクバーの処理中表示用の定義を追加します。
<Window.TaskbarItemInfo>
<TaskbarItemInfo x:Name="taskbarInfo"/>
</Window.TaskbarItemInfo>
◇ロジック
コンストラクタに以下の処理を追加します。
// 複数のスレッドからのアクセスを有効化
BindingOperations.EnableCollectionSynchronization(this.ZipRecords, new object());
以下のメソッドを追加します。
/// <summary>
/// データ読み込み中の画面表示
/// </summary>
/// <param name="loading">データ読み込み中の時にtrue, 読み込み終わったらfalseを設定する</param>
private void SetLoadingUI(bool loading)
{
if (loading)
{
// 処理中
// 画面全体を無効化
this.IsEnabled = !loading;
// 処理中メッセージを表示
loadingText.Visibility = Visibility.Visible;
// リストを隠す
listView.Visibility = Visibility.Collapsed;
// タスクバーアイコンを処理中表示にする
taskbarInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.Indeterminate;
}
else
{
// 処理終り
// 画面全体を有効化
this.IsEnabled = !loading;
// 処理中メッセージを隠す
loadingText.Visibility = Visibility.Collapsed;
// リストを表示
listView.Visibility = Visibility.Visible;
// タスクバーアイコンを通常に戻す
taskbarInfo.ProgressState = System.Windows.Shell.TaskbarItemProgressState.None;
}
}
/// <summary>
/// CSVファイル読み込みタスク
/// </summary>
/// <param name="filePath">CSVファイルパス</param>
/// <returns></returns>
private Task ReadCsvTask(string filePath)
{
return Task.Run(() => { ReadCsv(filePath); });
}
openMenu_Click
メソッドを修正します。
private void openMenu_Click
private async void openMenu_Click
this.IsEnabled = false;
// CSV読み込み
ReadCsv(dlg.FileName);
this.IsEnabled = true;
SetLoadingUI(true);
// CSV読み込み
await ReadCsvTask(dlg.FileName);
SetLoadingUI(false);
処理の流れは、await
を付けたReadCsvTask
メソッドが呼び出されたらopenMenu_Click
メソッドを一旦抜けます(他に並行して動いている処理があればそちらをやります)。
そして、ReadCsvTask
メソッドが終了したらその下の処理が実行されます。
ここでは、重たい処理(ReadCsvTask
)を実行する直前に画面を処理中表示にし、重たい処理が終わったら処理中表示を元に戻しています。
■動かしてみる
実行してみます。
一番大きい、全国一括データを読み込ませてみます。
↓
リストビューが隠れて代わりに処理中のテキストが表示されます。
前回と違って、読み込み中でもウィンドウを移動したりサイズ変更したりできます。
おしまい