我有一个 FileShare 爬虫(获取权限并将其放在某处以供以后审核)。目前,它正在启动多个线程来抓取同一文件夹(以加快进程)。
在 C# 中,每个SqlConnection
对象有自己的SqlTransaction
,由SqlConnection.BeginTransaction()
call.
这是当前解决方案的伪代码:
- 获取文件夹列表
- 对于每个文件夹获取子文件夹列表
- 对于每个子文件夹启动一个线程来收集文件共享
- 每个线程都会将收集到的数据保存到数据库中
- 对数据库运行审核报告
当子文件夹线程之一失败时就会出现问题。我们最终得到了“无法轻易检测到”的部分文件夹扫描。主要原因是每个线程都在单独的连接上运行。
我希望每个文件夹都在同一事务中提交,而不是进行不完整的扫描(当前情况,当某些线程失败时)。没有实施交易概念,但我正在评估这些选项。
根据评论这个答案 https://stackoverflow.com/a/23942409/837623,生产者/消费者队列将是一个选项,但不幸的是内存是有限的(由于启动线程的数量)。如果生产者/消费者空间被提交到磁盘以克服 RAM 限制,则执行时间将会增加(由于与内存 I/O 相比,磁盘 I/O 非常有限)。我想我陷入了记忆/时间的妥协。还有其他建议吗?
可以使用过时的绑定事务功能在与 SQL Server 的多个连接上共享同一事务。我从未使用过它,也不会基于它进行新的开发。这里似乎也没有必要。
难道不能让所有生产者使用相同的连接和事务吗?在它周围放一把锁。这显然会成为该过程的瓶颈,但它可能仍然足够快。
你说你执行INSERT
声明。对于批量插入,您可以使用SqlBulkCopy
类的速度要快得多。对行进行批处理,仅当缓冲了 >>1000 行时才执行批量插入。
我什至不认为这里需要生产者/消费者。它确实可以通过将生产与消耗进行管道化来提高性能,但它也引入了更复杂的线程。如果你想走这条路,你可能应该给IEnumerable<SqlDataRecord>
to the SqlBulkCopy
类直接将已生成的所有行流式传输到其中,无需中间缓冲。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)