0

在将应用程序变成更像后台任务的过程中,我注意到一些奇怪的行为。当我运行这样的东西时它工作正常(类似于我正在修改的旧代码):

using (Foo f = new Foo(stuff)) {
  f.doSomething();

  Application.EnableVisualStyles();
  Application.SetCompatibleTextRenderingDefault(false);
  Application.Run(new Form());
}

在后台进行此运行的第一步当然是删除对表单/渲染的引用:

using (Foo f = new Foo(stuff)) {
  f.doSomething();
}

然而,这种方式行不通。当我运行它时,我使用的库(与 Windows 窗体没有任何关系)不再正常工作。这没有我计划做的任何其他更改。只删除这三行。如果相关,Foo在实际代码中是一个创建 SSH 隧道的类(使用 SSH.NET 库),但它没有通过表单/设计器中的任何代码(直接或间接)引用,它只需要设置/拆除,以便建立连接。

该错误发生在连接到隧道之前,而是在尝试连接到远程主机并转发端口时发生。库报告连接已建立 ( IsConnectedis true),但是当端口转发启动时,它会报告异常并显示消息"Session is not connected"

4

1 回答 1

1

将您的应用程序转换为后台服务并不像删除这三行那么简单。特别Application.Run(new Form)是,根据 MSDN,启动应用程序的主线程:

开始在当前线程上运行标准应用程序消息循环,并使指定的表单可见。

https://msdn.microsoft.com/en-us/library/ms157902(v=vs.110).aspx

您可以查看重载Application.Run(),这将在没有表单的情况下启动主线程 - 但是您将在正确终止该线程时遇到问题。至少,您可以验证您的代码确实可以在没有明显显示表单的情况下工作。唯一需要注意的是,如果您的 mainForm对您的库有其他调用,现在必须在其他地方处理。

在基于 Win32 或 Windows 窗体的应用程序中,消息循环是处理用户事件(例如鼠标单击和键盘敲击)的代码例程。每个运行的基于 Windows 的应用程序都需要一个活动的消息循环,称为主消息循环。当主消息循环关闭时,应用程序退出。在 Windows 窗体中,当调用 Exit 方法或在运行主消息循环的线程上调用 ExitThread 方法时,此循环将关闭。

大多数 Windows 窗体开发人员将不需要使用此版本的方法。您应该使用 Run(Form) 重载来启动具有主窗体的应用程序,以便应用程序在主窗体关闭时终止。对于所有其他情况,使用 Run(ApplicationContext) 重载,它支持提供 ApplicationContext 对象以更好地控制应用程序的生命周期。

https://msdn.microsoft.com/en-us/library/ms157900(v=vs.110).aspx

老实说,您最好开始一个新的 Windows 服务或 WCF 项目。

于 2015-04-07T23:55:32.413 回答