Использование ThreadPool.QueueUserWorkItem для миллионов потоков

У меня есть необходимость обрабатывать миллионы файлов. В настоящее время я использую собственный менеджер потоков, чтобы выполнить работу, используя 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

Это имеет много недостатков, основные из которых заключаются в том, что загрузка ЦП и памяти высока, поскольку каждый из указанных выше потоков обрабатывает полный каталог, а не каждый файл независимо.

Итак, я переписал процесс. Теперь у меня есть класс, который будет выполнять процесс на уровне файлов и сообщать основному потоку результаты; вот так:

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

Вышеупомянутый класс работает как чудо и очень быстро, почти не использует памяти и почти ничего от процессора. Хотя я смог проверить это только с несколькими сотнями потоков, используя процесс Threading.Thread.

Теперь я хотел бы использовать ThreadPool.QueueUserWorkItem для выполнения вышеуказанного класса для каждого файла, позволяя системе контролировать количество потоков, которые будут запущены в любой момент времени. Однако я знаю, что не могу просто сбросить несколько миллионов потоков в ThreadPool, не заблокировав свой сервер. Я провел много исследований по этому вопросу, и мне удалось найти только примеры / обсуждения использования ThreadPool.QueueUserWorkItem для нескольких потоков. Что мне нужно, это запустить миллионы этих потоков.

Итак, у меня есть два вопроса: 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

0 ответов

Другие вопросы по тегам