掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
処理中ダイアログのメッセージを表示するには? (ID:144178)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
> (1)フォーム1の「開始」ボタンを押下 このイベント内のコードは、実質 1 行だけです。 Button1_Click で行うのは、RunWorkerAsync を呼び出すことだけです。 Sub Button1_Click(〜 BackgroundWorker1.RunWorkerAsync(〜) End Sub 実際の処理は、すべて BackgroundWorker1.DoWork に記述します。 その他、Button1_Click 内に付け加えることがあるとすれば、砂時計表示とか、 処理中に Form1 が閉じられないよう、FormClosing でキャンセルするための フラグ制御などですかね。 > (2)DBのバックアップを実行 > バックアップはバッチファイルを作成し、それをプロセス起動します。 あれ? 別プロセスなのですか。 呼び出し元/呼び出される側で、進捗状況の報告(プロセス間通信)は行われるのでしょうか? (パターン1)進捗確認は特に行われない。(単に終了を待つだけ) (パターン2)呼び出された側が、進捗を非同期通知する。 (パターン3)呼び出した側が、定期的に進捗を問い合わせる。 (パターン4)その他 > (3)処理中ダイアログを表示(フォーム2) BackgroundWorker1.DoWork 内(またはそこから呼ばれたメソッド)から、 Form2 (モードレス ダイアログ)を表示したり、Label 等のコントロールを 操作したりすることはできません。 進捗表示は、メインスレッド側で行う必要があるため、 Form2 を開く/表示更新/閉じることができるのは、基本的には Button1_Click 時、BackgroundWorker1_ProgressChanged時、そして BackgroundWorker1_RunWorkerCompleted時となります。 たとえば…。 Imports System.ComponentModel Public Class Form1 Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click Form2.Show(Me) BackgroundWorker1.WorkerReportsProgress = True BackgroundWorker1.RunWorkerAsync() End Sub Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork Dim bgw As BackgroundWorker = DirectCast(sender, BackgroundWorker) For n As Integer = 1 To 100 '長い処理の代わり System.Threading.Thread.Sleep(123) '進捗表示の依頼 bgw.ReportProgress(n, String.Format("処理中{0}%", n)) Next e.Result = "処理成功" End Sub Private Sub BackgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged '進捗表示 Form2.Label1.Text = e.UserState.ToString() End Sub Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted Form2.Close() MsgBox(e.Result) End Sub End Class > (4)プロセス終了まで待機 現在は、プロセスの起動〜終了までの処理を、どのように行っていますか? Process.WaitForExit によって同期待機させるなら、プロセス起動処理を メインスレッドにやらせるわけでは行かないので、BackgroundWorker を併用して、 Public Class Form1 Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Button1.Enabled = False BackgroundWorker1.RunWorkerAsync() End Sub Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork '電卓起動 Dim P As Process = Process.Start("CALC.EXE") P.WaitForExit() End Sub Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted MsgBox("電卓が閉じられた") Button1.Enabled = True End Sub End Class といった感じになるかと思います。 また、通知を非同期で行うのであれば、BackgroundWorker を使わずとも、 Process.Exited イベントで処理することができます。 Public Class Form1 Private WithEvents P As Process Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click Button1.Enabled = False '電卓起動 P = Process.Start("CALC.EXE") P.EnableRaisingEvents = True End Sub Private Sub P_Exited(ByVal sender As Object, ByVal e As System.EventArgs) Handles P.Exited Invoke(New MethodInvoker(AddressOf Completed)) End Sub Private Sub Completed() MsgBox("電卓が閉じられた") Button1.Enabled = True End Sub End Class > (5)処理中ダイアログを終了 > (6)後処理 これらは、BackgroundWorker1_RunWorkerCompleted 内で行うことになりますね。 > プログレスバーを表示している場合は、フォーム2にTimerコントロールを > 保持し、Timer.Tickイベントで確認しようかと思っていました。 Timer.Tick 内では、何を確認させるのでしょうか? その内容次第では、BackgroundWorker1 を使わず、Timer だけで処理できるかも知れません。
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.