为什么某些代码仅在我 create/run C# 中的表单时有效?

Why does some code only work when I create/run a form in C#?

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

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

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

在后台创建此 运行 的第一步当然是删除对 form/rendering 的引用:

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

但是,这种方式行不通。当我 运行 那个时,我使用的库(与 Windows 表单没有任何关系)不再正常工作。这没有我计划做的任何其他更改。只删除那三行。如果相关,实际代码中的 Foo 是创建 SSH 隧道(使用 SSH.NET 库)的 class,但未通过任何代码(直接或间接)引用它在 form/designer 中,只需将其设置为 up/torn 即可建立连接。

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

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

Begins running a standard application message loop on the current thread, and makes the specified form visible.

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

您可以查看重载 Application.Run(),它会在没有表单的情况下启动主线程 - 但是您将无法正确终止该线程。至少,您可以在不显示表单的情况下验证您的代码是否确实有效。唯一需要注意的是,如果您的主 Form 对您的图书馆有其他调用,现在必须在其他地方处理。

In a Win32-based or Windows Forms application, a message loop is a routine in code that processes user events, such as mouse clicks and keyboard strokes. Every running Windows-based application requires an active message loop, called the main message loop. When the main message loop is closed, the application exits. In Windows Forms, this loop is closed when the Exit method is called, or when the ExitThread method is called on the thread that is running the main message loop.

Most Windows Forms developers will not need to use this version of the method. You should use the Run(Form) overload to start an application with a main form, so that the application terminates when the main form is closed. For all other situations, use the Run(ApplicationContext) overload, which supports supplying an ApplicationContext object for better control over the lifetime of the application.

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

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