我有一个方法来处理来自使用多个线程的数据表中的行,它将所有工作项排队,然后检查它们是否已经全部处理过,而不是离开方法直到它们有.
它似乎在开发中工作正常,但是当我进入服务器(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
angry person.. 5
您不应该这样做,等待所有行都完成.
你应该使用一种通知方法,从你的处理代码中,告诉一段代码"嘿,我刚完成一行".
这样,您可以更轻松地跟踪已处理的行数.
我会这样做的方式:
添加一个初始化为0的Int32值,用于跟踪已处理的值
使用Interlocked.Increment在您的委托中增加此值
增加计数器后,在委托中设置一个事件对象
在你的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); }
不要忘记在完成后关闭事件对象.
您不应该这样做,等待所有行都完成.
你应该使用一种通知方法,从你的处理代码中,告诉一段代码"嘿,我刚完成一行".
这样,您可以更轻松地跟踪已处理的行数.
我会这样做的方式:
添加一个初始化为0的Int32值,用于跟踪已处理的值
使用Interlocked.Increment在您的委托中增加此值
增加计数器后,在委托中设置一个事件对象
在你的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); }
不要忘记在完成后关闭事件对象.