Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.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
.net 通知ThreadPool.QueueUserWorkItem有关内存要求_.net_Multithreading_Memory_Threadpool_Queueuserworkitem - Fatal编程技术网

.net 通知ThreadPool.QueueUserWorkItem有关内存要求

.net 通知ThreadPool.QueueUserWorkItem有关内存要求,.net,multithreading,memory,threadpool,queueuserworkitem,.net,Multithreading,Memory,Threadpool,Queueuserworkitem,我们正在设计一个应用程序,用户可以设置多个任务同时运行。我们使用ThreadPool.QueueUserWorkItem来设置正在运行的任务。那部分运行良好 我们确实有一个问题,这些任务可能会消耗500 MB+的内存。我们使用内存映射I/O来管理内存。但是,当用户设置10多个任务同时运行时,线程池将启动所有这些任务,并且有时会出现内存不足和异常。我们可以很好地处理错误 我想知道的是,是否有一种方法可以在处理队列时将要消耗的内存考虑在内,即保持任务排队,直到有足够的内存存在?我能否告知线程池我们需

我们正在设计一个应用程序,用户可以设置多个任务同时运行。我们使用ThreadPool.QueueUserWorkItem来设置正在运行的任务。那部分运行良好

我们确实有一个问题,这些任务可能会消耗500 MB+的内存。我们使用内存映射I/O来管理内存。但是,当用户设置10多个任务同时运行时,线程池将启动所有这些任务,并且有时会出现内存不足和异常。我们可以很好地处理错误


我想知道的是,是否有一种方法可以在处理队列时将要消耗的内存考虑在内,即保持任务排队,直到有足够的内存存在?我能否告知线程池我们需要多少内存(我们可以粗略估计)

线程池对您在任务中所做的事情一无所知。你需要自己确保这一点。您可以管理long类型的全局变量,该变量表示所有正在运行的作业在峰值时可能需要的字节总数。当线程池安排一项任务时,首先检查该变量如果已经过高,则等待当前正在运行的任何任务退出。然后再次检查


一个低技术的解决方案是使用100ms睡眠间隔的轮询。高科技版本将使用某种涉及事件的等待方案。

好的,如果您可以获得每个任务的内存估计值,您可能可以通过在池中保留粗略的CS保护内存使用计数来实现这一点。在提交任务之前将此计数相加,并在任务结束之前让任务调用'memRelease'函数从中减去,然后检查是否可以立即运行任何内容(请参阅下文)


如果某个线程想要提交任务,并且(通过将其需求与CS中的当前使用情况进行比较)发现“预算”中没有足够的内存来运行该任务,您可以将其推到并发队列/列表中等待,直到有足够的内存。每当任务完成并调用“memRelease”时,它都会添加到内存buget并迭代队列/列表(首先锁定它),以尝试查找现在可以使用增加的可用内存运行的内容。如果是这样,它会将任务提交到线程池。

您可以通过ThreadPool.SetMaxThreads控制线程池中的线程数。因此,您可以做的是设置最大线程数

ThreadPool.SetMaxThreads = new PerformanceCounter("Memory", "Available MBytes").RawValue / 500;

PerformanceCounter(“内存”、“可用MB”).RawValue->返回以MB为单位的可用内存

听起来根本不适合使用线程池。TP线程应该只执行短时间运行的少量工作,不超过半秒。使用数量有限的线程对象,最多只能使用Environment.ProcessorCount和线程安全队列来为它们提供工作。谢谢,我认为我们将用这种方法编写我们自己的池。可能存在一些问题-负载沉重的系统可能会通过不断加载新到达的具有较小需求的任务来锁定高内存需求的任务。应用某种抗饥饿算法是可能的,可能通过在添加任务时迭代“挂起”列表来决定是提交新任务,还是只将其添加到挂起列表的末尾,以允许建立足够的内存来运行一些需要大量时间且已等待很长时间的挂起任务。这是一个流程全局设置。你绝对不应该这样做。不要用局部解决方案解决局部问题。此外,它也不能解决问题,因为作业有不同的内存需求。找不到静态最大线程数。