0

何百万ものファイルを処理する必要があります。現在、カスタム スレッド マネージャーを使用して、DataGridView を使用してスレッドを追跡し、タイマーを使用してさらにスレッドを開始できるかどうかを確認します。のようなもの(sudo):

Private Sub ThreadManager()
    If AVailableThreads > 0 then
        Dim t as Threading.Thread = New Thread(AddressOf MyThread)
        t.Start()
        AvailableThreads = AvailableThreads - 1
        ThreadManager()
    End If
End Sub

これには多くの欠点があります。主な欠点は、上記の各スレッドが各ファイルではなく完全なディレクトリを処理するため、CPU とメモリの使用率が高くなることです。

だから私はプロセスを書き直しました。これで、ファイル レベルでプロセスを実行し、結果をメイン スレッドに報告するクラスが作成されました。そのようです:

Imports System.IO

Public Class ImportFile

    Public Class ImportFile_state
        Public ID as Long = Nothing
        Public FilePath as String = Nothing
        Public Result as Boolean = False
    End Class

    Public Event ReportState(ByVal state as ImportFile_state)

    Dim _state as ImportFile_state = New ImportFile_State

    Public Sub New(ByVal ID as Long, ByVal FilePath as String)
        MyBase.New()
        _state.ID = ID
        _state.FilePath = FilePath
    End Sub

    Public Sub GetInfo()
        'Do the work here, but just return the result for this demonstration
        Try
            _state.Result = True
        Catch ex As Exception
            _state.Result = False
        Finally
            RaiseEvent ReportState(_state)
        End Try
    End Sub
End Class

上記のクラスは魔法のように機能し、非常に高速で、メモリをほとんど使用せず、CPU もほとんど使用しません。Threading.Thread プロセスを使用して数百のスレッドでしかこれをテストできませんでしたが。

ここで、ThreadPool.QueueUserWorkItem を使用してファイルごとに上記のクラスを実行し、システムが特定の時間に実行するスレッドの数を制御できるようにします。ただし、サーバーをロックせずに数百万のスレッドを ThreadPool にダンプすることはできません。私はこれについて多くの調査を行いましたが、いくつかのスレッドで ThreadPool.QueueUserWorkItem を使用する例/議論しか見つけることができませんでした。私が必要としているのは、何百万ものこれらのスレッドを起動することです。

したがって、2 つの質問があります。1) ThreadPool.QueueUserWorkItem を使用してこれだけ多くのスレッドを実行する必要があるか、2) サーバーをロックすることなくこのプロセスを実行するには、以下のコードで十分ですか?

これまでの私のコードは次のとおりです。

        For Each subdir As String In Directory.GetDirectories(DirPath)
            For Each fl In Directory.GetFiles(subdir)
                'MsgBox(fl)
                Dim f As ImportFile = New ImportFile(0, fl)
                AddHandler f.ReportState, AddressOf GetResult
                ThreadPool.QueueUserWorkItem(New Threading.WaitCallback(AddressOf f.GetInfo))
                ThreadPool.GetAvailableThreads(worker, io)
                Do While (worker) <= 0
                    Thread.Sleep(5000)
                    ThreadPool.GetAvailableThreads(worker, io)
                Loop
            Next
        Next
4

0 に答える 0