2

我有一个 FileShare 爬虫(获取权限并将它们放在某个地方以供以后审核)。目前它正在启动多个线程来爬取同一个文件夹(以加快进程)。

在 C# 中,每个SqlConnection对象都有自己的SqlTransaction,由SqlConnection.BeginTransaction()调用发起。

这是当前解决方案的伪代码:

  1. 获取文件夹列表
  2. 对于每个文件夹,获取子文件夹列表
  3. 为每个子文件夹启动一个线程来收集文件共享
  4. 每个线程将收集到的数据保存到数据库
  5. 在数据库上运行审计报告

当其中一个子文件夹线程失败时,就会出现问题。我们最终会扫描“无法轻易检测到”的部分文件夹。主要原因是每个线程都在单独的连接上运行。

我想让每个文件夹在同一个事务中提交,而不是扫描不完整(当前情况,当某些线程失败时)。没有实现交易概念,但我正在评估选项。

根据这个答案的评论,生产者/消费者队列将是一个选项,但不幸的是内存是一个限制(由于启动线程的数量)。如果生产者/消费者空间被提交到磁盘以克服 RAM 限制,则执行时间将增加(由于磁盘 I/O 与内存 I/O 相比非常有限)。我想我被记忆/时间妥协所困扰。还有其他建议吗?

4

1 回答 1

1

可以使用过时的绑定事务功能在与 SQL Server 的多个连接上共享同一个事务。我从未使用过它,也不会基于它进行新的开发。这里似乎也没有必要。

你不能让所有的生产者使用相同的连接和事务吗?把锁放在它周围。这显然会成为流程的瓶颈,但它可能仍然足够快。

你说你执行INSERT语句。对于批量插入,您可以使用SqlBulkCopy更快的类。批处理行并仅在缓冲 >>1000 行时执行批量插入。

我什至看不到这里需要生产者/消费者。它确实会通过流水线化生产与消费来提高性能,但它也引入了更复杂的线程。如果你想走这条路,你可能应该给IEnumerable<SqlDataRecord>SqlBulkCopy一个直接将所有已经生成的行流式传输到它而不需要中间缓冲。

于 2014-05-30T13:10:31.787 回答