我创建了窗口服务,使用 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.
}
禁用后点击图片查看设置WinSCP中的“传输恢复”设置,文件已成功传输。