在开始之前,我必须为两件事道歉。一是我很难用简洁的方式解释事情。二是由于我工作的公司的性质,我需要有点模糊。
我正在努力增强我继承的应用程序的功能。这是一个非常密集的应用程序,运行着我公司日常业务的很大一部分。因此,我仅限于我可以更改的范围——否则我可能会从头开始重写它。无论如何,这是我需要做的:
我有几个线程都执行相同的任务,但在不同的数据输入流上。每个线程通过来自另一个软件系统的 API 进行交互,我们支付许可以写入所谓的通道。不幸的是,我们只许可了一定数量的同时运行的频道,所以这个应用程序应该根据需要将它们打开和关闭。
每个线程都应该等待,直到有可用的通道,为自己锁定通道并执行其处理,然后释放通道。不幸的是,我不知道如何做到这一点,尤其是跨多个线程。我也真的不知道要在 Google 或这个网站上搜索什么,否则我可能会得到我的答案。这是我的想法:
处理通道号分布的类。每个线程调用这个类的一个成员。当它这样做时,它会进入一个队列并阻塞,直到通道处理类识别出我们有一个通道,向等待线程发出一个通道可用的信号并将通道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 中的 .NET Framework 3.5。我确信必须为此建立某种机制,但正如我所说,我不知道我应该搜索哪些关键字。任何将我指向正确方向的输入(即要使用的特定 .NET 框架类或代码示例)将不胜感激。如果我需要详细说明任何事情,请告诉我,我会尽我所能。
编辑:我遇到的另一个问题是,这些通道可以在此应用程序之外由用户手动打开/关闭(或作为用户启动事件的结果)。我不关心在线程使用通道时关闭通道(它会抛出异常,然后在下次通过时重新启动。但问题是没有恒定数量的线程争夺一个常数通道数(如果用户手动打开一个,则减少计数等)。这两项都是可变的,所以我不能依赖没有外力的事实(即,这组线程之外的东西,即为什么我通过我的数据库进行一些处理以确定可用的频道号)