VB.NET覚書

VB.NETの覚書
[個人メモ] [仕事メモ] [アイデア] [Ruby]
[TIPS] [対応表] [コメント書き方] [.NET Tips] [VB中学校] [VB.NET の入門サイト] [VB.NET コーディング標準 ] [VBレスキュー] [NonSoft]

2019-02-12

clsBackgroundworker

Imports System.ComponentModel
'http://multithreadingapp.blogspot.com/

Enum ST_NO
    ''' <summary>
    ''' アイドル状態
    ''' </summary>
    E_IDLE
    ''' <summary>
    ''' 動作中
    ''' </summary>
    E_BUSY
    ''' <summary>
    ''' キャンセル
    ''' </summary>
    E_CANCEL
    ''' <summary>
    ''' エラー
    ''' </summary>
    E_ERR
    ''' <summary>
    ''' 終了
    ''' </summary>
    E_DONE
    ''' <summary>
    ''' 総数
    ''' </summary>
    E_ALL_NUM
End Enum
''' <summary>
''' 処理率(100で終了)
''' </summary>
''' <param name="Para">パラメータ</param>
''' <param name="Result">応答</param>
Public Delegate Function job(Para As String, ByRef Result As String) As Integer

''' <summary>
''' マルチスレッド(Backgrowndworker)クラス
''' </summary>
''' <remarks>
''' 使用例
''' 
''' Public Class Form1
''' 
'''    Dim WithEvents bgw As New clsBackGroundWorker
''' 
'''    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
''' 
'''        bgw.m_job = Function(Para As String, ByRef Result As String) As Integer
'''                        MsgBox(Para)
''' 
'''                        Result = "終了"
''' 
'''                        Return clsBackGroundWorker.MAX_PROGRESS
'''                    End Function
''' 
'''        bgw.start("開始")
''' 
'''    End Sub
''' 
'''    Private Sub bgw_completed(ByVal sender As Object, ByVal e As System.EventArgs) Handles bgw.completed
''' 
'''        MsgBox(bgw.getResult())
''' 
'''    End Sub
''' 
''' End Class
''' </remarks>
Public Class clsBackGroundWorker

    Public Const MAX_PROGRESS = 100

    Private bw As BackgroundWorker = New BackgroundWorker
    Private m_progress As Integer = 0
    Private m_status_msg As String = ""
    Private m_status_no As Integer = 0
    Private m_result As String = ""

    ''' <summary>
    ''' 実行する処理を記載 
    ''' </summary>
    Public m_job As job

    ''' <summary>
    ''' 終了処理
    ''' </summary>
    Public Event completed(ByVal sender As Object, ByVal e As EventArgs)

    Sub New()
        bw.WorkerSupportsCancellation = True
        bw.WorkerReportsProgress = True

        AddHandler bw.DoWork, AddressOf bw_DoWork
        AddHandler bw.ProgressChanged, AddressOf bw_ProgressChanged
        AddHandler bw.RunWorkerCompleted, AddressOf bw_RunWorkerCompleted

        m_status_msg = "IDLE"
        m_status_no = ST_NO.E_IDLE

    End Sub

    ''' <summary>
    ''' ステータスメッセージ
    ''' </summary>
    Function getStatusMessage() As String
        Return m_status_msg
    End Function

    ''' <summary>
    ''' ステータス変数
    ''' </summary>
    Function getStatusNo() As Integer
        Return m_status_no
    End Function

    Private Sub bw_DoWork(ByVal sender As Object, ByVal e As DoWorkEventArgs)

        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)
        Dim Ret As Integer = 0
        Dim Result As String = ""
        m_status_msg = "BUSY"
        m_status_no = ST_NO.E_BUSY

        Do While True

            Ret = m_job(CType(e.Argument, String), Result)

            If bw.CancellationPending = True Then
                e.Cancel = True
                Exit Do
            Else
                ' Perform a time consuming operation and report progress.
                bw.ReportProgress(Ret)
                If Ret = MAX_PROGRESS Then
                    Exit Do
                End If
            End If
        Loop

        e.Result = Result

    End Sub

    Private Sub bw_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs)
        m_progress = e.ProgressPercentage
    End Sub

    Private Sub bw_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs)

        If e.Cancelled = True Then
            m_status_msg = "Canceled!"
            m_status_no = ST_NO.E_CANCEL
        ElseIf e.Error IsNot Nothing Then
            m_status_msg = "Error: " & e.Error.Message
            m_status_no = ST_NO.E_ERR
        Else
            m_status_msg = "Done!"
            m_status_no = ST_NO.E_DONE
            'MsgBox("Done")
            m_result = e.Result.ToString()
            RaiseEvent completed(Me, New EventArgs)
        End If

    End Sub

    ''' <summary>
    ''' スレッドを開始
    ''' </summary>
    Public Sub start(x As String)
        If Not bw.IsBusy = True Then
            bw.RunWorkerAsync(x)
        End If
    End Sub

    ''' <summary>
    ''' キャンセル処理
    ''' </summary>
    Public Sub cancel()
        If bw.WorkerSupportsCancellation = True Then
            bw.CancelAsync()
        End If
    End Sub

    ''' <summary>
    ''' 処理状況を返す(0-100)
    ''' </summary>
    Public Function getProgress() As Integer
        Return m_progress
    End Function

    ''' <summary>
    ''' 結果
    ''' </summary>
    Public Function getResult() As String

        Return m_result

    End Function

End Class

使用

Public Class Form1

    Dim WithEvents bgw As New clsBackGroundWorker

    Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click

        bgw.m_job = Function(Para As String, ByRef Result As String) As Integer
                        MsgBox(Para)

                        Result = "終了"

                        Return clsBackGroundWorker.MAX_PROGRESS
                    End Function

        bgw.start("開始")

    End Sub

    Private Sub bgw_completed(ByVal sender As Object, ByVal e As System.EventArgs) Handles bgw.completed

        MsgBox(bgw.getResult())

    End Sub

    Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load

    End Sub
End Class



backgroundworker 引数戻り値

http://www.atmarkit.co.jp/fdotnet/dotnettips/436bgworker/bgworker.html

Imports System.ComponentModel

Public Class Form1

  ' [スタート]ボタンのイベント・ハンドラ
  Private Sub buttonStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles buttonStart.Click
    buttonStart.Enabled = False

    ' 時間のかかる処理を別スレッドで開始
    bgWorker.RunWorkerAsync(100)
    ' DoWorkイベント発生
  End Sub

  ' 時間のかかる処理を行うメソッド
  Private Sub bgWorker_DoWork(ByVal sender As System.Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles bgWorker.DoWork
    ' 別スレッドで実行されるため、このメソッドでは
    ' UI(コントロール)を操作してはいけない

    ' このメソッドへのパラメータ
    Dim bgWorkerArg As Integer = CType(e.Argument, Integer)

    ' senderの値はbgWorkerの値と同じ
    Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)

    ' 時間のかかる処理
    For i As Integer = 1 To bgWorkerArg

      System.Threading.Thread.Sleep(100)

      Dim percentage As Integer = i * 100 / bgWorkerArg ' 進ちょく率
      worker.ReportProgress(percentage)
      ' ProgressChangedイベント発生
    Next

    ' このメソッドからの戻り値
    e.Result = "すべて完了"

    ' この後、RunWorkerCompletedイベントが発生
  End Sub

  Private Sub bgWorker_ProgressChanged(ByVal sender As Object, ByVal e As System.ComponentModel.ProgressChangedEventArgs) Handles bgWorker.ProgressChanged
    ' 進ちょく状況の表示
    Me.Text = e.ProgressPercentage & "%完了"
    progressBar.Value = e.ProgressPercentage
  End Sub

  Private Sub bgWorker_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles bgWorker.RunWorkerCompleted
    ' 処理結果の表示
    Me.Text = e.Result.ToString()
    MessageBox.Show("正常に完了")

    buttonStart.Enabled = True
  End Sub
End Class
トラックバック - http://sub.g.hatena.ne.jp/garyo/20190212