Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/amazon-web-services/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Multithreading 为什么不是';t ThreadPool.GetAvailableThreads是否正常工作?_Multithreading - Fatal编程技术网

Multithreading 为什么不是';t ThreadPool.GetAvailableThreads是否正常工作?

Multithreading 为什么不是';t ThreadPool.GetAvailableThreads是否正常工作?,multithreading,Multithreading,我有一个方法,可以使用多个线程处理数据表中的行,它将所有工作项排队,然后检查它们是否都已处理,直到处理完毕才离开该方法 它在开发中似乎工作得很好,但当我将其放入服务器(64位)进行测试时,它不会等待方法结束。它甚至似乎不执行Thread.Sleep()调用,因为该方法会立即退出 离开该方法后,它将继续处理数据行,但这不是我想要的 有什么想法吗? 谢谢 Public Sub-ProcessAll(ByVal集合作为DataTable,ByVal processDelegate作为WaitCallb

我有一个方法,可以使用多个线程处理数据表中的行,它将所有工作项排队,然后检查它们是否都已处理,直到处理完毕才离开该方法

它在开发中似乎工作得很好,但当我将其放入服务器(64位)进行测试时,它不会等待方法结束。它甚至似乎不执行Thread.Sleep()调用,因为该方法会立即退出

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

有什么想法吗? 谢谢

Public Sub-ProcessAll(ByVal集合作为DataTable,ByVal processDelegate作为WaitCallback)
将工作项设置为数据行
Dim availableThreads为整数
Dim completionPortThreads作为整数
SetMaxThreads(最大线程数,最大线程数)
'循环处理每个挂起记录并将其添加到线程队列
对于collection.Rows中的每个工作项
ThreadPool.QueueUserWorkItem(processDelegate,workItem)
下一个
'线程池是后台线程的集合,因此我们需要采取措施阻止主线程继续运行
做
线程。睡眠(1000)
GetAvailableThreads(availableThreads,completionPortThreads)
'如果所有线程都是空闲的(我们如何检查所有线程是否已完成),请等待几秒钟以确保
如果availableThreads=最大线程数,则
线程。睡眠(5000)
GetAvailableThreads(availableThreads,completionPortThreads)
如果结束
可用时循环读取<最大线程数
端接头

您不应该以这种方式等待所有行完成

相反,您应该使用一种通知方法,该方法将从处理代码中告诉某些代码“嘿,我刚刚完成了一行”

这样,您可以更轻松地跟踪处理了多少行

我会这样做:

  • 添加一个初始化为0的Int32值,用于跟踪已处理的数量
  • 使用Interlocated.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);
    }
    
    private volatile Int32\u Processed=0;
    私有自动恢复事件_RowProcessedEvent=新自动恢复事件(false);
    ... 在您的代表中:
    联锁增量(参考处理);
    _RowProcessedEvent.Set();
    ... 在您的主要方法中:
    while(_Processed

    完成事件对象后,不要忘记关闭它。

    您试图解决的根本问题是什么?你为什么有这个代码?它真的很简单;我有一个数据库中需要单独处理的实体列表,我希望处理速度非常快。回答很好,非常感谢。对任何其他人来说都是旁注;WaitOne(Int32)直到.NET3.5SP1优秀的解决方案才被引入。谢谢@LasseV.Karlsen
    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);
    }