質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

3回答

13708閲覧

Backgroundworkerの処理を一時停止および再開する、ということは可能でしょうか?

zanac

総合スコア25

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

.NET Framework 4.0

Microsoft Windows用のソフトウェア開発環境/実行環境である .NET Frameworkの4番目のメジャーバージョンです。

Visual Studio 2013

Microsoft Visual Studio 2013は、Microsoftによる統合開発環境(IDE)であり、多種多様なプログラミング言語に対応しています。 Visual Studio 2012の次のバージョンです

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2016/12/11 05:58

###前提・実現したいこと
backgroudworkerを用いてコピーする処理を実装しております。

その中で実現方法が見えないものがあり、困っております。

コピー中に表示する画面にキャンセルボタンを設け、そのボタンを押すと、
キャンセル確認画面を表示します。その画面で「はい」ボタンを押すと、そこで初めてコピーをキャンセルする、

というやり方を考えてるのですが、実現方法がまったく見えないです・・・

キャンセル確認画面を表示中は、backgroudworkerの処理を停止し、
キャンセル確認画面で「はい」を押すと、backgroudworkerの処理をキャンセル処理を呼び出し、
「いいえ」を押すと、backgroudworkerの処理を再開する、ということができればとは思うのですが・・・
(キャンセルボタンを押してすぐキャンセル処理をする、であれば下記のソースコードで実現はできております。)

Backgroundworkerの処理の一時停止および再開する、ということはできるのでしょうか?

助けれいただければ幸いです・・・

###該当のソースコード
C#

public Copying() { _backgroundWorker.DoWork += new DoWorkEventHandler(Worker_DoWork); _backgroundWorker.ProgressChanged += new ProgressChangedEventHandler(Worker_ProgressChanged); _backgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(Worker_RunWorkerCompleted); // 進捗状況の報告をできるようにする _backgroundWorker.WorkerReportsProgress = true; // キャンセル処理をできるようにする _backgroundWorker.WorkerSupportsCancellation = true; // バックグラウンド処理の実行 _backgroundWorker.RunWorkerAsync(); } // コピー処理 void Worker_DoWork(object sender, DoWorkEventArgs e) { if (_backgroundWorker.CancellationPending) { // キャンセル処理 e.Cancel= true break; } // 実際のコピー処理 } // コピー中画面でキャンセルボタンクリック private void Cancel_Click(object sender, RoutedEventArgs e) { if( true == _backgroundWorker.IsBusy) { // キャンセル要求 _backgroundWorker.CancelAsync(); } } // 処理が完了 void Worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) { if ( true == e.Cancelled) { //キャンセルが押下された場合の処理 } } // 閉じるボタン(×ボタン)押下された(キャンセルボタンクリックと同じ処理) private void Closing_Click(object sender, CancelEventArgs e) { if (true == _backgroundWorker.IsBusy) { // キャンセル要求 _backgroundWorker.CancelAsync(); } }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

まず前提として、コピーは中断可能な処理でしょうか?

実際のコピー処理が以下のような形式のものであれば中断と再開は可能です。

void DoWork(object o, DoWorkEventArgs e) { // コピー処理がなんらかのループによって実行されている for (...) { // 最初に一時停止する方法をここに実装し次にキャンセレーショントークンを見る await semaphore.WaitAsync(); try { if (cancellationToken.IsCancellationRequested) { // cancelの実行 } // コピーの部分的な実行 } finally { semaphore.Release(); } } }

後は、画面側でセマフォの取得をし、メッセージボックスを表示すればよいと思います。

var task = semaphore.WaitAsync(); // var result = MessageBox.Show(...) await task; // if (result ... ) MessageBoxの結果に対応したキャンセル処理等 semaphore.Release();

ただ、わざわざサスペンドしなくてもキャンセルだけ実行可能であれば良いようにも思えます。
キャンセル確認画面を表示中に処理を止める必要は本当にあるのでしょうか?

キャンセル確認画面を表示中は、backgroudworkerの処理を停止し、

キャンセル確認画面で「はい」を押すと、backgroudworkerの処理をキャンセル処理を呼び出し、
「いいえ」を押すと、backgroudworkerの処理を再開する、ということができればとは思うのですが・・・

※キャンセル確認画面で「はい」を押すと、backgroudworkerの処理をキャンセルするだけで良いのでは?

投稿2016/12/13 03:53

編集2016/12/14 01:09
haru666

総合スコア1591

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

こんにちは。

泥臭いですが、フラグで制御する感じです。
少なくとも、Backgroundworkerの標準機能としては用意されてないです。

UIスレッドとバックグラウンドスレッドで共有できるフラグを用意し、
UIスレッドでキャンセルダイアログを表示したタイミングでフラグを更新します。

要はCancelAsynのCancellationPendingと同じで、
DoWorkで定期的にステータスのチェックをする必要があるでしょう。

BackgroundWorker.CancellationPending


Pausing and Resuming Threads

私は使ったことないですが、Threadクラスには過去上記のような仕組みが用意されていたようですが、現在は推奨されていないようですので、やはりフラグで制御したほうが良いのではないかなという感じです。

投稿2016/12/11 10:02

Tak1wa

総合スコア4791

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

zanac

2016/12/14 13:32

結構難しいのですね・・・ まだ試しておりませんが、 回答いただいたやり方を参考にやってみます。ありがとうございました。
guest

0

普通にダイアログ表示して選択させて、結果を反映させればいいのですが、
ワーカースレッドからのダイアログ表示はそのままではできませんね。

delegate を使用して、Invoke で関数を呼ぶか、僕がたまにやる簡易的な事は、
WorkerReportsProgress プロパティを Trueにし、ProgressChanged を設定して
ReportProgress を呼び出します。
このイベント内では、コントロールを制御する事ができるので、まあ、なんでもできます。
ワーカー内では、フラグ更新待ちでもしてイベント終了まで待てばいいのではないでしょうか。

投稿2016/12/11 08:18

mugicya

総合スコア1046

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問