我有一个运行后台线程的应用程序,它打开一个用于执行操作的WinSCP会话,如下所示:
new Thread(() => {
//do stuff
SessionOptions options = new SessionOptions
{
//options
};
using(Session session = new Session())
{
bool success = false;
foreach (var ip in IPs)
{
options.HostName = ip.Value;
try
{
session.Open(options);
success = true;
break;
}
catch (Exception)
{
}
}
if(success)
{
CommandExecutionResult result = session.ExecuteCommand(*some command*);
result.Check();
someVariable = result.Output;
}
}
//do stuff
})
{
IsBackground = true
}.Start();
现在我注意到,如果我在using
中关闭应用程序,线程确实会停止但WinSCP会话仍然打开(可能是因为线程被中止了?)如果我重复这个过程,我当然会结束更多的WinSCP会话。如何关闭我在应用程序中打开的特定会话?
编辑:添加更多在using
块中发生的事情。
您可以使用Session.Dispose方法来杀死底层进程。
请参阅WinSCP的文档:https://winscp.net/eng/docs/library_session_dispose
另请注意本文中的文字:
如果会话已打开,则关闭它,终止基础WinSCP进程,删除XML日志文件并处置对象。
与Session.Close相反,之后不可能重用该对象。
我已将您的代码放到C#控制台应用程序中,并将Thread.Sleep
添加到主线程和后台线程中。如果我运行应用程序(在Windows 7和10上测试)并关闭它,或者即使我突然从任务管理器中删除它,WinSCP子流程也彻底消失了。
这是预期的,因为子进程在与.NET代码相同的Windows job中运行。因此,无论.NET代码是什么,它都是一个负责清理WinSCP子进程的操作系统。所以你的应用程序中有一些奇怪的东西。
无论如何,如果要确保WinSCP会话中止,只需在关闭应用程序时从主线程调用Session.Abort
。
我的解决方案,在Form_FormClosing事件处理程序,只是把这些行:
foreach (var process in Process.GetProcessesByName("WinSCP"))
{
process.Kill();
}
(Process.GetCurrentProcess()).Kill();