処理中に進捗率表示とキャンセルボタンで中止はasync、await、Task.Run、Progress、CancellationTokenSource
時間のかかる処理中に
- 進捗率を表示
- キャンセルボタンで処理中止
いつもどおりよくわかっていないけどできた!のでメモしとく
進捗率表示更新は
WPF/Windowsフォーム:時間のかかる処理をバックグラウンドで実行するには?(async/await編)[C#/VB]:.NET TIPS - @IT
http://www.atmarkit.co.jp/ait/articles/1512/02/news019.html
こちらからのコピペなので問題ないはず
キャンセルの処理はあちこち見ながら自分で書いたので間違っているかも
でも期待どおりの動きなのでOK
デザイン画面
時間のかかる処理は別スレッドで実行する
それにはasyncとawait、System.ThreadingクラスのTask.Runを使う
これで処理中にアプリが固まることがなくなるので
キャンセルボタンを押すことができるようになる
表示更新、Progressクラスを使う
別スレッドから直接UIスレッドの表示を更新することはできないので
表示更新用のメソッドを持たせたProgressオブジェクトを作成して
これを時間のかかる処理メソッドに渡す
受け取る側はProgressじゃなくてIProgressで受け取る
処理中にProgressのReportメソッドを実行して表示更新する
処理のキャンセル
CancellationTokenSourceクラスのTokenを使う
これを時間のかかる処理に渡しておく
キャンセルボタンが押されたらキャンセルを発行
時間のかかる処理中にはキャンセルが発行されたかどうかの判定をする
発行されたら停止処理
UI
UIはユーザーインターフェース、アプリのウィンドウやボタンとかのコントロールのことらしい
UIスレッド(メインスレッド)と別スレッド(ワーカースレッド)
普通の処理は全部UIスレッド
時間のかかる処理をUIスレッドで行うと終了するまでUI(アプリ)が固まる
これを避けるためにUIスレッドとは別スレッドで時間のかかる処理を実行する
別スレッド
別スレッドを使うにはasyncとawait、System.ThreadingクラスのTask.Runを使う
これでUIスレッドは自由になるからUI(アプリ)は固まることがなくなるので
表示更新やボタンをクリックとかできるはずなんだけど
別スレッドからはUIにアクセスできない
UIスレッドからはボタンとかのコントロールにアクセスできるけど
別スレッドからはボタンとかのコントロールにアクセスできない
進捗率表示を更新したい
進捗率は別スレッドで行っている時間のかかる処理中に変化するから、別スレッドから表示更新することになる、けど別スレッドからUIにはアクセスできないっていう矛盾
これを解決するのに使うのがProgressクラス
ProgressBarのValueとTextBlockのTextを更新するメソッドを用意しておいて
これを時間のかかる処理に渡す(72行目)
受け取るときの引数の型はIProgressで受け取る(88行目)
(100行目)
キャンセルの方法もだいたい同じ感じで、使うのはCancellationTokenSourceクラス
フィールドにCancellationTokenSourceを用意しておいて
キャンセルボタンのクリックイベントの中で
CancellationTokenSourceのCancelメソッドでキャンセルを発行するようにしておいて
別スレッド実行前にCancellationTokenSourceのインスタンスを作成して
そのTokenプロパティを
別スレッドで実行する時間のかかる処理に渡す
95行目、キャンセルされていたら処理中止
表示更新はProgress
キャンセルはCancellationTokenSourceの違いくらいで同じ感じだねえ
これらを別スレッドとして実行するメソッドに渡して中でそれぞれの動作をさせる
参照したところ
WPF/Windowsフォーム:時間のかかる処理をバックグラウンドで実行するには?(async/await編)[C#/VB]:.NET TIPS - @IT
http://www.atmarkit.co.jp/ait/articles/1512/02/news019.html
【C# WPF】Task Runの引数にControl.Textを使うと別のスレッドに所有され... - Yahoo!知恵袋
https://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q11182269146
非同期で複数処理を実行し、対話式で制御する - Qiita
https://qiita.com/haminiku/items/cc299c1ed94d7ba3f9ec
コード
アプリ
関連記事
続きは2018/05/07
画像処理中のプログレスバー更新とキャンセルボタンで中止 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15494790.html
2015/11/7、あれからもう3年…なの?
BackgroundWorkerの使い方メモ.NET VB、大量の画像ファイルを読み込んでListViewに縮小画像を表示 ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/13625471.html
今ではBackgroundWorkerよりも今回の記事の方法のがいいみたい?