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

好,

这是这些“概念性问题”中的一个,但我希望我能在正确的方向上找到一些指示.首先是期望的场景:

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

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

我的基本方法很简单,创建某种“池”,我保持10个开放的SFTP连接.然后查询第一个工作人员以获取目录列表.如果获得此列表,则发送下一个免费工作人员(例如1-10,第一个也可以再次免费)以获取子目录详细信息.一旦有工人自由,就把他送到子包装.等等…

我知道ThreadPool,简单的线程并做了一些测试.令我困惑的是以下内容:我基本上需要……

>我创建的线程列表,比如说10
>将所有线程连接到服务器
>如果连接断开,请创建新的线程/ sftp客户端
>如果有工作要做,请先获取第一个免费线程并处理工作

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

以下是一个好主意:

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

好的,到目前为止……

顺便说一句,我也可以使用PRISM事件和命令,但我认为这个问题是无关紧要的.也许是EventModel来表示“工作包”的完成处理……

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

最佳答案 一堆小调:

如果你使用的是一些内部使用ThreadPool的.NET API,那么你就无法进行无限等待,因为操作系统拥有ThreadPool中的线程,这些线程意味着“短暂”使用然后返回给操作系统,即最强健的行为.当然,如果由于长时间运行处理而最终占用它们,操作系统可以根据需要增加线程池,但更好的设计是避免这种行为.

如果您在XP上运行,您可能还想避免使用ThreadPool(操作系统级别,因此是.NET),因为它在Vista中被修复/重新签名,之后,XP版本被认为不太健壮.

如果您确实使用了ThreadPool,那么您最终会将异步工作排队,因为它已经在等待工作了.

编写自己的ThreadManager相当容易,你可以在其上找到很多例子,但是一如既往这一点应该保持尽可能简单.

对于您的第三个要点,最好恢复SFTP连接,而不是终止整个线程.如果你杀掉一个线程(假设你的ThreadManager可以处理它,永远不会从操作系统ThreadPool中删除线程),而不是首先将未处理的作业返回到某个队列,感觉就像是太多的工作.

点赞