ssh.net throw操作会话超时卡住

ssh.net throw operation session has timed out and get stuck

我创建了 window 服务,使用 SSH.net 每 600 秒从 sFTP 服务器读取文件 在 OnStart 中我创建了计时器

timer = new Timer(TimerCallback, null, 0, timeDelay);

TimerCallBack 是使用 SSH.net 的函数。在读取文件之前的连接中,我有连接到 sFTP 服务器的代码,如下所示

            var FILE_READ_FLAG = false;
            try
            {
                req = new SftpClient(ftpHost, ftpLogin, ftpLoginPassword);
                req.Connect();
                if (req.IsConnected)
                {
                    directories = req.ListDirectory(ftpPath);
                    FILE_READ_FLAG = true;
                }
            }
            catch (Exception e)
            {

                EventLog.WriteEntry(sSource,"ERROR : " + GetFullMessageFromException(e), 
                                    EventLogEntryType.Information, 234);
                
                FILE_READ_FLAG = false;
            }
            if (FILE_READ_FLAG){
               // read file and insert to database
            }

问题是当服务 运行 和异常发生时,服务可以每 600 秒再次 运行 但出现错误

Session operation has timed out
   at Renci.SshNet.Session.WaitOnHandle(WaitHandle waitHandle, TimeSpan timeout)
   at Renci.SshNet.Session.WaitOnHandle(WaitHandle waitHandle)
   at Renci.SshNet.Session.Connect()
   at Renci.SshNet.BaseClient.Connect()

服务无法再次 运行,当我尝试停止并重新启动服务时似乎卡住了,Windows 显示警报消息无法及时停止,我必须通过 cmd 终止服务并启动手动

我的问题是,为什么另一个异常可以用 try/catch 块处理,但由于这个错误,服务不会再次使用计时器 运行 我遗漏或使用错误的东西?谢谢

您已经创建了一个对象 SftpClient。查看代码,它没有得到正确处理,而且您也没有调用断开连接。如果出现错误,系统可能会挂起,因为有一个打开的连接。

但是您将客户端设置为变量(即 req = new SftpClient(ftpHost, ftpLogin, ftpLoginPassword),因此断开连接/处置可能在别处调用。尽管我仍然建议重新构建代码,以便您从 SFTP 客户端获取数据并立即断开连接/处理。最好尽量减少连接打开的时间。

考虑以下因素:

List<SftpFile> files = null; 
using (SftpClient sftp = new SftpClient(host, username, password)) // using will dispose SftpClient
{
    try
    {
        sftp.Connect();    
        files = sftp.ListDirectory(ftpPath).ToList();    
        sftp.Disconnect();
    }
    catch (Exception e)
    {
        EventLog.WriteEntry(sSource,"ERROR : " + GetFullMessageFromException(e), 
                                EventLogEntryType.Information, 234);
    }
}

if(files.any())
{
   // Process the files.
}