始める前に、2つのことをお詫びする必要があります。一つは、簡潔に説明するのがとても難しいということです。二つ目は、私が働いている会社の性質上、やや漠然としている必要があるということです。
継承したアプリケーションの機能強化に取り組んでいます。これは非常に集中的なアプリケーションであり、私の会社の日常業務のかなりの部分を実行します。このため、私は変更できる範囲に制限されています。そうでない場合は、おそらく最初から書き直します。とにかく、これが私がする必要があることです:
同じタスクを実行するスレッドがいくつかありますが、データ入力ストリームは異なります。各スレッドは、ライセンスを支払う別のソフトウェアシステムからのAPIを介して相互作用し、チャネルと呼ばれるものに書き込みます。残念ながら、同時に実行されているチャネルのライセンスは一定数しかないため、このアプリケーションは必要に応じてそれらをオフにすることになっています。
各スレッドは、使用可能なチャネルができるまで待機し、チャネルを自分自身でロックして処理を実行してから、チャネルを解放する必要があります。残念ながら、特に複数のスレッドでこれを行う方法がわかりません。また、私はグーグルやこのサイトを何で検索すればいいのか本当にわからない、あるいは私はおそらく私の答えを持っているだろう。これは私の考えでした:
チャネル番号の配布を処理するクラス。各スレッドは、このクラスのメンバーを呼び出します。これを行うと、チャネル処理クラスがチャネルがあることを認識し、待機中のスレッドにチャネルが使用可能であることを通知してチャネルIDを渡すまで、キューに入り、ブロックします。これを調べてもどこから始めればいいのかわからない。以下に、それがどのように機能すると思うかについて、恐ろしく書かれたPsuedoCodeをいくつか示します。
Public Class ChannelHandler
Private Shared WaitQueue as New Queue(of Thread)
'// calling thread adds itself to the queue
Public Shared Sub WaitForChannel(byref t as thread)
WaitQueue.enqueue(t)
End Sub
Public Shared Sub ReleaseChannel(chanNum as integer)
'// my own processing to make the chan num available again
End Sub
'// this would be running on a separate thread, polling my database
'// for an available channel, when it finds one, somehow signal
'// the first thread in the queue that its got a channel and here's the id
Public Shared Sub ChannelLoop()
while true
if WaitQueue.length > 0 then
if thereIsAChannelAvailable then '//i can figure this out my own
dim t as thread = ctype(WaitQueue.dequeue(), Thread)
lockTheChannel(TheAvailableChannelNumber) 'performed by me
'// signal the thread, passing it the channel number
t => SignalReady(theAvailableChannelNumber) '// how to signal?
end if
end if
end while
End Sub
End Class
その後
'// this inside the function that is doing the processing:
ChannelHandler.requestChannel(CurrentThread)
while (waitingForSignal) '// how?
block '// how?
dim channelNumber as int => getChannelNumberThatWasSignaledBack
'// perform processing with channelNumber
ChannelHandler.ReleaseChannel(channelNumber)
VB.NETで.NETFramework3.5を使用しています。このためにすでに何らかのメカニズムが構築されている必要があると確信していますが、私が言ったように、どのキーワードを検索すべきか正確にはわかりません。私を正しい方向に向ける入力(つまり、使用する特定の.NET Frameworkクラスまたはコードサンプル)をいただければ幸いです。何か詳しく説明する必要がある場合は、お知らせください。できる限りのことをさせていただきます。
編集:私が抱えているもう1つの問題は、これらのチャネルをこのアプリケーションの外部から、ユーザーが手動で(またはユーザーが開始したイベントの結果として)オン/オフできることです。スレッドが使用しているときにチャネルがシャットダウンされることは関係ありません(例外がスローされ、次に通過したときに回復します。しかし、問題は、一定の数のスレッドが一定の数を争っているわけではないということです。チャネルの数(ユーザーが手動で1つをオンにすると、カウントが減るなど)両方の項目が可変であるため、外力がないという事実(つまり、このスレッドのセットの外側にあるもの、つまり利用可能なチャネル番号を決定するためにDBを介して処理を行う理由)