我用线程池复制粘贴文件,一共1000个文件,大小在几百KB到10MB,不管最大线程设成几,都会卡死,线程池里的方法也用begininvoke了也不行。
复制粘贴文件是用文件流进行复制,每次读取1024*4大小的字节,读写间没有写延时
你不好奇几乎所有的下载软件,转换工具都会设定5-10个并行任务么
我们说5个并行任务,而非啥子“最大并行线程”,why,因为线程是切换的,我们是可以允许同时最大并行10个线程,但线程是切换的。他来回切换10次,那么其实就是100个线程在跑。
所以这里需要做的事情是限制任务量而非限制线程量。
当然他没chartgpt说的那么复杂了,一个SemophoreSlim就够了
简单逻辑
SemophoreSlim slim=new SemophoreSlim(10);
async task copyfile( 源,目标,报告对象Process)
{
await slim.waitone() //获取执行权限,虽然你外面可以循环,可以线程,可以并行,但是我就10个令牌,只有拿到令牌的才做,没有拿到令牌的就等着,
//做你要做的事情
slim.释放令牌
}
写在最后,所谓“线程”不是越多越好,IO任务主要瓶颈在IO上,而非cpu上。说copy文件磁盘效率也许你无法理解。
换成网络了你应该能理解了,5个下载任务已经把下行500M带宽都用光了,那么你在开100个线程还有意义么?后面无论开多少个线程都还是抢那500M带宽,反而每个任务下载时间更长
换到文件copy上其实一样的,5-10个任务就行了,后面无论多少个都是等前面一个完成了交出令牌了在进去
源于chatGPT仅供参考
在使用线程池复制粘贴文件时卡死的问题,可能是由于以下原因导致的:
1. 磁盘 I/O 操作阻塞:大量的文件复制操作可能会导致磁盘 I/O 阻塞,从而影响到主界面的响应。这可能发生在读取和写入文件的过程中。
2. 线程池资源限制:如果同时启动了大量线程,线程池的线程数量可能会达到上限,导致线程调度出现问题。这可能导致性能下降或系统资源不足。
为了解决这个问题,可以考虑以下几点:
1. 采用异步的方式进行文件复制:使用 `async/await` 关键字结合异步文件操作(如 `FileStream` 的异步方法)来进行文件复制操作,这样可以避免线程阻塞。
2. 控制并发数量:在使用线程池进行文件复制时,可以采用限制并发数量的方式,避免同时启动过多的复制线程。可以尝试将最大线程数设置为一个适当的值,并使用 `SemaphoreSlim` 或类似的机制来限制并发操作。
3. 使用进度报告:如果主界面需要显示复制进度,可以考虑使用进度报告机制,通过回调或事件的方式将复制进度实时通知给主界面,而不是等待所有文件复制完成后再更新界面。
4. 考虑使用并行处理:根据您的情况,如果文件复制是磁盘 I/O 密集型操作,可以考虑使用 `Parallel.ForEach` 或类似的方法来实现并行的文件复制,以充分利用多核 CPU 的性能。
请注意,在进行大量文件复制时,还要确保目标路径的可用性和目标磁盘空间足够。
希望以上建议对您有所帮助。如果您需要更详细或具体的代码示例,请提供相关代码片段或更多背景信息,以便我进一步协助您。
你怎么写的代码,invoke/begininvoke本质上是回到了单线程,你的代码如果有不正确的同步或者你把复制放在 invoke 里,那肯定卡了。