解析が常に読み取りよりも高速であることが確実な場合は、非常に簡単に行うことができます。スレッドA(UIスレッドをブロックしないスレッド)がファイルを読み取り、新しいスレッドBを開始して、ファイルの内容をに渡します。それ(スレッドの代わりにタスクを使用すると簡単になります)。それをループに入れれば完了です。解析が高速であるため、スレッドAが新しいスレッドを開始する前に2番目のスレッド/タスクが終了します。したがって、同時に実行されるスレッドは2つだけで、メモリ内のファイルは2つだけです。
回線取得プロセスが完了するのを待っています。解析スレッドは、配列を解析する準備ができているかどうかを知る必要があります。
正しく理解できているかわかりませんが、上記の「解決策」で解決できます。常に新しいスレッド/タスクを開始するため、ファイルが完全に読み取られた場合にのみ。
更新:処理が(常に)読み取りよりも高速でない場合は、たとえば次のように実行できます。
Private MaxTasks As Integer = 4
Private Async Sub ReadAndProcess(ByVal FileList As List(Of String))
Dim ProcessTasks As New List(Of Task)
For Each fi In FileList
Dim tmp = fi
Console.WriteLine("Reading {0}", tmp)
Dim FileContent = Await Task.Run(Of Byte())(Function() As Byte()
Return File.ReadAllBytes(tmp)
End Function)
If ProcessTasks.Count >= MaxTasks Then
Console.WriteLine("I have to wait!")
Dim NextReady = Await Task.WhenAny(ProcessTasks)
ProcessTasks.Remove(NextReady)
End If
Console.WriteLine("I can start a new process-task!")
ProcessTasks.Add(Task.Run(Sub()
Console.WriteLine("Processing {0}", tmp)
Dim l As Long
For Each b In FileContent
l += b
Next
System.Threading.Thread.Sleep(2000)
Console.WriteLine("Done with {0}", tmp)
End Sub))
Next
Await Task.WhenAll(ProcessTasks)
End Sub
Private Async Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim ofd As New OpenFileDialog
ofd.Multiselect = True
If ofd.ShowDialog = Windows.Forms.DialogResult.OK AndAlso ofd.FileNames.Count >= 1 Then
ReadAndProcess(ofd.FileNames.ToList)
End If
End Sub
アイデア(通常、.Netでは4ダースの方法で実装できます)は、自分で設定した制限に達するまで、新しい処理タスクをスケジュールするというものです。それが達成された場合は、タスクの準備ができるまで「待機」し、新しいタスクを開始します。
UPDATE2:TPL libを使用すると、次のようになります。
Private Sub Doit()
Dim ABProcess As New ActionBlock(Of Tuple(Of String, Byte()))(Sub(tp)
Console.WriteLine("Processing {0}", tp.Item1)
Dim l As Long
For Each el In tp.Item2
l += el
Next
System.Threading.Thread.Sleep(1000)
Console.WriteLine("Done with {0}", tp.Item1)
End Sub, New ExecutionDataflowBlockOptions With {.MaxDegreeOfParallelism = 4, .BoundedCapacity = 4})
Dim ABRead As New ActionBlock(Of String())(Async Sub(sarr)
For Each s In sarr
Console.WriteLine("Reading {0}", s)
Dim t = New Tuple(Of String, Byte())(s, File.ReadAllBytes(s))
Dim taken = Await ABProcess.SendAsync(t)
Console.WriteLine("Output taken = {0}", taken)
Next
Console.WriteLine("All reading done")
End Sub)
Dim ofd As New OpenFileDialog
ofd.Multiselect = True
If ofd.ShowDialog = Windows.Forms.DialogResult.OK Then
ABRead.Post(ofd.FileNames)
End If
End Sub
どのバージョンが「より良い」か...個人的な好みかもしれません;)新しいTPLブロックは時々非常にブラックボックスっぽいので、個人的には「手動」バージョンを好むかもしれません。