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

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

ただいまの
回答率

88.62%

自動バックアップ処理をバックグラウンドで実装したい

解決済

回答 4

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 364

python_user

score 12

お世話になっております。
現在、案件で指定周期にて定期的にバックアップを動かす処理を実装しようとしているのですが、バックアップの処理は実行できるものの、スレッドが固まっているような状態になってしまいます。自身で書籍や他の方のブログ等参考にしてみたのですが、どうにもうまく実装できません・・・。
どなたかお手数ではございますが、実装方法等ご教示いただけますと幸いです。

前提・実現したいこと

・データバックアップ処理は実装できたが、メインフォームが固まった状態になってしまうので、
バックグラウンドで実行させたい。
・メインフォームからタイマー処理で呼び出された以下コード処理内にバックグラウンドで
実行させる為のコードを追記したい。

発生している問題・エラーメッセージ

申し訳ありません、エラーメッセージ等は出力しておりません・・・。
BackgroundWorkerメソッドは勉強してみたのですが、自身の知識及び理解力が乏しく、
問題解決に至らない次第でございます。

該当のソースコード

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        '即時で動かす(稼働検証済)
        Dim p21 As New System.Diagnostics.Process
        RichTextBox2.ForeColor = Color.Blue
        RichTextBox2.Text = "即時バックアップ実行中"
        'バックアップ前に削除データを作成する
        Dim files As String() = System.IO.Directory.GetFiles(
                        "バックアップ元のIP", "*.JPG", System.IO.SearchOption.AllDirectories)
        ListBox1.Items.AddRange(files)

        Using st As New System.IO.StreamWriter("C:\text\deletefile_list.txt",
                    False, System.Text.Encoding.Default)
            For i As Integer = 0 To ListBox1.Items.Count - 1
                'ファイルへ書込み
                st.WriteLine(ListBox1.Items(i).ToString())
            Next
            'ファイル閉じる
            st.Close()
        End Using

        '実データのバックアップ
        p21.StartInfo.FileName = "C:\Users\user\Desktop\M1_Backup_MachineData.bat"
        p21.Start()
        p21.WaitForExit()
        System.IO.File.Delete("C:\text\Backup#1.txt")

        '事前の削除データを読み込み、データを削除する
        If System.IO.File.Exists("C:\text\delete_machine#PC1_1.txt") Then
            'データ削除コード(稼働検証済)
            Dim hReader As New System.IO.StreamReader("C:\text\deletefile_list.txt", System.Text.Encoding.Default)

            ' 読み込んだ結果をすべて格納するための変数を宣言する
            Dim stResult As String = String.Empty

            ' 読み込みできる文字がなくなるまで繰り返す
            While (hReader.Peek() >= 0)
                ' ファイルを 1 行ずつ読み込む
                Dim stBuffer As String = hReader.ReadLine()
                ' 読み込んだものを追加で格納する
                System.IO.File.Delete(stBuffer)
                'stResult &= stBuffer & System.Environment.NewLine
            End While
            ' hReaderを閉じる(正しくはオブジェクトの破棄を保証するを参照)
            hReader.Close()

        End If

        RichTextBox2.ForeColor = Color.Black
        RichTextBox2.Text = "即時バックアップ実行済み"
    End Sub

試したこと

書籍、他の方のブログを参考にさせて頂いた程度でございます。

補足情報(FW/ツールのバージョンなど)

プログラムの実行環境:Windows10 Pro(64bit)
自身の開発環境:Visual Studio 2017 .net FrameWork(ver.4.6.1)(OS:Windows10 Pro(64bit))
作成しているのはWindows Form になります。
※修正・追記致しました。

上記処理はテストで作成した為、Button1が押された時のアクションになっていますが、
実際はタイマー処理にて指定日時が到来した時に呼び出されます。
綺麗なコードでない為、大変申し訳なく思っておりますが、ご教示の程何卒宜しくお願い致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • SurferOnWww

    2020/01/06 09:40

    何を作っているのですか? Windows Firms? WPF? ASP.NET Web Forms? その他?

    相手方の実行環境の「相手方」とはなんですか?

    Core か .NET Framework のどっちですか? そのバージョンは?

    キャンセル

  • python_user

    2020/01/06 09:52

    申し訳ございません、修正致しました。
    相手方とは、プログラムの実行環境の事です。
    誤解を招くような表記、お詫びいたします。

    キャンセル

  • YAmaGNZ

    2020/01/06 10:10

    提示コードをどうバックグラウンドで実行するようにするか質問するより、このように組んでみたのだが、こういうエラーとなり実行できない。どのように改善すべきですかと質問したほうがいいような気がします。
    現状の質問であれば、現状のコードをマルチスレッド化する作業依頼とも取られかねません。
    また、実現する方法(BackgroundWorkerとかTaskを使えばどうですか?というレベル)が回答として返ってきて、結局理解できないのではないでしょうか?

    キャンセル

  • python_user

    2020/01/06 10:17

    大変申し訳ございませんでした。
    自身が質問させていただくレベルではないと感じました。
    ご意見ありがとうございました。

    キャンセル

回答 4

+2

Windows Froms アプリで時間のかかる処理を同期実行すると処理が終わるまで UI がブロックされる(フリーズしたように操作不能になる)が、それを避けるため、時間のかかる処理を非同期で(別のスレッドで)実行したいということと理解してレスします。

Button1_Click イベントハンドラの中に時間のかかる処理があるのだと理解していますが、であれば、その部分を別メソッドに切り分けて、その別メソッドを非同期で実行するというのではいかがでしょう。

.NET Framework 4.6 なら async / await / Task.Run を利用して容易に非同期呼び出しができると思います。

具体例は以下の記事を見てください。タイトルが「デリゲートを利用した」となってますが、async / await / Task.Run を利用した例も含まれています。記事の中の TimeCosumingMethod メソッドが時間のかかる処理を切り出したものと思ってください。

デリゲートを利用した非同期メソッドの実装
http://surferonwww.info/BlogEngine/post/2019/06/19/coding-asynchronous-method-by-using-delegate-in-windows-forms-application.aspx

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/06 10:26

    ご認識頂いている通りでございます。文章が稚拙で申し訳ありません。
    ご提示頂いた記事を参考にさせて頂き、わからないところがあれば再度質問させて頂く事もあるかと思いますが、
    その際はまた宜しくお願い致します。

    キャンセル

checkベストアンサー

+1

バックアップの処理を別スレッドで実行させるようにすればどうでしょうか

別スレッドにした場合、実行終了のチェックがややこしくなるとか、そこから直接GUIにアクセスできないなどの難しいところは出てきますが、調べれば対処法が出てくると思います

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/06 09:57

    ご回答ありがとうございます。
    自身でもいろいろと調べていく中で、マルチスレッド処理だとBackgroundWorkerが
    便利だと書いてあり、そちらを採用しようかと思っていた次第です。
    ただ、自身の調べ方が悪いせいもありますが、同じような記事やブログが多く、
    少し困惑してしまいましたので、今回質問させて頂きました。

    キャンセル

  • 2020/01/06 10:06

    なら、まずはそれで実装しましょう。
    割と簡単に別スレッド処理を走らせることが出来ます。
    ましかし、回答に書いたように難しいところも出てきます。
    それはその問題にぶち当たった場合にまた聞いていただけるとよろしいかと思います

    キャンセル

  • 2020/01/06 10:15

    そうですね、おっしゃる通りですね。まず実践してみます。
    また質問させていただく事があるかと思いますが、その際はまた宜しくお願い致します。

    キャンセル

+1

他の回答でスレッドであったり非同期であったりの回答がありますが、他に同時に動かしたい処理がないのであれば(バックアップ処理のみが唯一の処理であるなら)そんなことをする必要はありません。
VisualBasicの伝統的なDoEventsを要所要所で実行すればよいでしょう。
「要所」というのはループの先頭あたりがよいでしょう。
ループの深いところに入れてしまうと他のプロセスに処理が奪われてしまいパフォーマンス劣化の恐れがあります。と思いましたが、ご提示のコードではシンプルなループ処理でしたのでその心配は不要そうです。
まずはDoEvents化を行い動作を見てもらいたいです。
そこで遅いなどの問題があったら非同期化を検討するべきかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2020/01/06 10:42

    ご回答ありがとうございます。
    DoEventsメソッドは初耳でした・・・。
    現状、他に動かす処理はタイマー処理で時間と日付を確認しているくらいなのですが、
    まず実装してみたいと思います。

    キャンセル

  • 2020/01/06 11:00

    もしバッチファイルの実行に一番時間がかかっているのであれば、思ったより効果が薄いと思います。
    バッチファイルでどのような処理を行っているのか分かりませんが、VB側で実装できるのであれば、ファイルの列挙ループ内で1ファイル毎にバックアップ処理→ファイルの削除と行い、そこにDoEventsを入れればいいような気がします。

    キャンセル

  • 2020/01/06 11:04

    あぁ、コードをよく読んでなかった。
    バックアップの実体はバッチファイルなんですね。
    そうすると効果は薄い可能性大です。

    キャンセル

  • 2020/01/06 11:32

    情報が不足し過ぎており、大変申し訳ございません。
    バックアップの実体はバッチファイルです。
    中身はrobocopyを使って、単純に差分バックアップを取得しているだけです・・・。

    キャンセル

0

皆さまお世話になっております。
上記コードにつきまして、BackgroundWorkerコンポーネントを実装する事で解決致しました。
稚拙な文章や質問にも関わらず、アドバイスを頂いた方々にお礼申し上げます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 88.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る