我有一个方法来处理来自使用多个线程的数据表中的行,它将所有工作项排队,然后检查它们是否已经全部处理过,而不是离开方法,直到它们有。
它似乎在开发中运行良好,但是当我进入服务器(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
答案 0 :(得分:5)
你不应该这样做,等到所有的行都完成了。
你应该使用一种通知方法,从你的处理代码中,告诉一段代码“嘿,我刚刚完成一行”。
这样,您可以更轻松地跟踪已处理的行数。
我会这样做:
即。类似的东西:
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);
}
不要忘记在完成后关闭事件对象。