为什么ThreadPool.GetAvailableThreads不工作?

Iai*_*ult 4 multithreading

我有一个方法来处理来自使用多个线程的数据表中的行,它将所有工作项排队,然后检查它们是否已经全部处理过,而不是离开方法直到它们有.

它似乎在开发中工作正常,但是当我进入服务器(64位)进行测试时,它不会在方法结束时等待.它似乎甚至没有进行Thread.Sleep()调用,因为该方法会立即退出.

它会在离开方法后继续处理数据行,但这不是我想要的.

有任何想法吗?谢谢

Public Sub ProcessAll(ByVal collection As DataTable, ByVal processDelegate As WaitCallback)
        Dim workItem As DataRow
        Dim availableThreads As Integer
        Dim completionPortThreads As Integer


        ThreadPool.SetMaxThreads(MAX_THREADS, MAX_THREADS)

        ' loop round processing each pending record adding them to the Thread Queue
        For Each workItem In collection.Rows
            ThreadPool.QueueUserWorkItem(processDelegate, workItem)
        Next

        ' The ThreadPool is a collection of background threads, thus we need to do something to stop the main thread from moving on
        Do
            Thread.Sleep(1000)
            ThreadPool.GetAvailableThreads(availableThreads, completionPortThreads)
            ' in the case that all threads are free (how we check all are complete) wait a few seconds just to make sure
            If availableThreads = MAX_THREADS Then
                Thread.Sleep(5000)
                ThreadPool.GetAvailableThreads(availableThreads, completionPortThreads)
            End If
        Loop While availableThreads < MAX_THREADS
End Sub
Run Code Online (Sandbox Code Playgroud)

ang*_*son 5

您不应该这样做,等待所有行都完成.

你应该使用一种通知方法,从你的处理代码中,告诉一段代码"嘿,我刚完成一行".

这样,您可以更轻松地跟踪已处理的行数.

我会这样做的方式:

  1. 添加一个初始化为0的Int32值,用于跟踪已处理的值
  2. 使用Interlocked.Increment在您的委托中增加此值
  3. 增加计数器后,在委托中设置一个事件对象
  4. 在你的main方法中,我会等待事件被设置,然后检查计数器.如果不够高,请回路并再次等待.

即.就像是:

private volatile Int32 _Processed = 0;
private AutoResetEvent _RowProcessedEvent = new AutoResetEvent(false);

... in your delegate:
Interlocked.Increment(ref _Processed);
_RowProcessedEvent.Set();

... in your main method:
while (_Processed < collection.Rows.Count)
{
    _RowProcessedEvent.WaitOne(Timeout.Infinite);
}
Run Code Online (Sandbox Code Playgroud)

不要忘记在完成后关闭事件对象.