在 C# 中使用 SFTP 时的线程最佳实践

Chr*_*ert 5 c# sftp multithreading

好的,

这更多是这些“概念性问题”之一,但我希望我能得到一些正确方向的指示。首先是所需的场景:

  • 我想查询 SFTP 服务器的目录和文件列表
  • 我想同时上传或下载文件

使用 Tamir.SharpSsh 提供的 SFTP 类,这两件事都非常容易,但如果我只使用一个线程,那就有点慢了。特别是子目录的递归变得非常“UI 阻塞”,因为我们正在谈论 10.000 个目录。

我的基本方法很简单,创建某种“池”,在其中保留 10 个打开的 SFTP 连接。然后向第一个工作人员查询目录列表。如果获得了该列表,则发送下一个空闲工人(例如1-10,第一个也再次空闲)以获取子目录详细信息。一旦有工人空闲,就派他到子子目录去。等等...

我知道线程池、简单的线程并做了一些测试。让我有点困惑的是:我基本上需要......

  • 我创建的线程列表,例如 10 个
  • 将所有线程连接到服务器
  • 如果连接断开,则创建一个新线程/sftp 客户端
  • 如果有工作要做,则占用第一个空闲线程并处理工作

我目前不确定实现细节,特别是“要做的工作”和“维护线程列表”部分。

这是一个好主意吗:

  • 将工作封装在一个对象中,其中包含工作描述(路径)和回调
  • 将线程发送到无限循环,等待 100 毫秒等待工作
  • 如果 SFTP 死了,要么恢复它,要么杀死整个线程并创建一个新线程
  • 如何封装这个,我是写自己的“10ThreadsManager”还是有一些

好吧,到目前为止...

顺便说一句,我也可以使用 PRISM 事件和命令,但我认为问题是不相关的。也许 EventModel 会发出“工作包”处理完成的信号......

感谢您的任何想法,评论家..克里斯

Chr*_*s O 2

一堆小注释:

如果您使用的某些内部使用 ThreadPool 的 .NET API,那么您不能进行无限等待,因为操作系统拥有来自 ThreadPool 的线程,这些线程旨在“短暂”使用,然后返回到操作系统,即最稳健的行为。当然,如果您由于长时间运行的处理而最终占用了线程池,操作系统可以根据需要增加线程池,但更好的设计是避免这种行为。

如果您在 XP 上运行,您可能还想避免使用 ThreadPool(操作系统级别,因此 .NET),因为它在 Vista 和更高版本中已修复/取消,XP 版本被认为不太健壮。

如果您确实使用线程池,那么您最终会将异步工作排队到它,因为它已经在等待工作完成。

编写自己的 ThreadManager 相当容易,您可以找到很多相关示例,但一如既往,此类事情应尽可能保持简单。

对于您的第三个要点,恢复 SFTP 连接比终止整个线程更好。如果你杀死一个线程(假设你的 ThreadManager 可以处理这个问题,当然,永远不要杀死操作系统线程池中的线程),那么它首先必须将未处理的作业返回到某个队列,感觉工作量太大了。