当前位置:  开发笔记 > 运维 > 正文

为什么ThreadPool.GetAvailableThreads不工作?

如何解决《为什么ThreadPool.GetAvailableThreads不工作?》经验,为你挑选了1个好方法。

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

它似乎在开发中工作正常,但是当我进入服务器(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);
}

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



1> angry person..:

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

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

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

我会这样做的方式:

    添加一个初始化为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);
}

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

推荐阅读
刘美娥94662
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有