简体   繁体   English

为什么只有在C#中创建/运行表单时某些代码才起作用?

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

In the process of turning an application into something more like a background task, I noticed some odd behavior. 在将应用程序转换为类似于后台任务的过程中,我注意到了一些奇怪的行为。 It works fine when I run something like this (similar to the old code I'm modifying): 当我运行类似这样的东西时,它工作正常(类似于我正在修改的旧代码):

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

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

The first step towards making this run in the background was of course to remove the references to the form/rendering: 在后台进行此操作的第一步当然是删除对表单/渲染的引用:

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

That way doesn't work, however. 但是,这种方式行不通。 When I run that, a library that I use (which doesn't have anything to do with Windows forms) no longer works correctly. 当我运行该库时,我使用的库(与Windows窗体无关)不再正常工作。 This is without any of the other changes I planned to do whatsoever. 这没有我计划做的任何其他更改。 Only removing those three lines. 仅删除这三行。 If it is relevant, Foo in the actual code is a class that creates an SSH tunnel (using the SSH.NET library), but it is not referenced (directly or indirectly) through any code in the form/designer, it just needs to be set up/torn down so a connection can be made. 如果相关,则实际代码中的Foo是一个类(使用SSH.NET库)创建SSH隧道的类,但没有通过表单/设计器中的任何代码(直接或间接)对其进行引用,它只需要设置/拆除,以便建立连接。

The error occurs before the connection to the tunnel is made, but instead when trying to connect to the remote host and forward the ports. 该错误在建立与隧道的连接之前发生,但是在尝试连接到远程主机并转发端口时发生。 The library reports a connection is made ( IsConnected is true ), but when port forwarding is started, it reports an exception with the message "Session is not connected" 该库报告已建立连接( IsConnectedtrue ),但是启动端口转发时,它将报告消息"Session is not connected"的异常。

Converting your application to a background service isn't as simple as removing those three lines. 将您的应用程序转换为后台服务并不像删除这三行代码那么简单。 In particular, Application.Run(new Form) is what starts the main thread of the application, per MSDN: 特别是,根据MSDN, Application.Run(new Form)是启动应用程序主线程的源:

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 https://msdn.microsoft.com/en-us/library/ms157902(v=vs.110).aspx

You could look into the overload Application.Run() , which would start the main thread without a form - but then you will have issues properly terminating that thread. 您可以查看过载Application.Run() ,它会在不使用表单的情况下启动主线程-但随后会出现问题,无法正确终止该线程。 At the very least, you could verify that your code does in fact work without visibly displaying a form. 至少,您可以验证您的代码确实可以正常工作,而无需显示表单。 The only caveat is if your main Form has other calls to your library that now have to be handled elsewhere. 唯一需要注意的是,如果您的主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. 在基于Win32或Windows Forms的应用程序中,消息循环是代码中的一个例程,用于处理用户事件,例如鼠标单击和键盘敲击。 Every running Windows-based application requires an active message loop, called the main message loop. 每个正在运行的基于Windows的应用程序都需要一个活动的消息循环,称为主消息循环。 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. 在Windows窗体中,当调用Exit方法或在运行主消息循环的线程上调用ExitThread方法时,将关闭此循环。

Most Windows Forms developers will not need to use this version of the method. 大多数Windows窗体开发人员将不需要使用此版本的方法。 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. 您应该使用Run(Form)重载来启动具有主窗体的应用程序,以使应用程序在主窗体关闭时终止。 For all other situations, use the Run(ApplicationContext) overload, which supports supplying an ApplicationContext object for better control over the lifetime of the application. 对于所有其他情况,请使用Run(ApplicationContext)重载,该重载支持提供ApplicationContext对象,以更好地控制应用程序的生命周期。

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

To be honest, you'd probably be best off just starting a new Windows Service or WCF project. 老实说,最好只启动一个新的Windows Service或WCF项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么我的 C# Xml 代码仅在我枚举变量可枚举时才有效 - Why does my C# Xml code only work when I enumerate variable enumerable 为什么此C#代码无法运行可执行文件? - Why does this C# code to run executables not work? 为什么我的C#Windows窗体中的代码不起作用? - Why does my code in my c# windows form not work? 为什么当我想通过 C# 运行 GAMS 代码时,visual studio 给我错误? - Why does visual studio gives me error when I want to run the GAMS code via C#? 为什么当我使用 !!= C# 时代码会被编译 - Why does the code get compiled when I use !!= C# 为什么此代码仅在从Visual Studio内部运行时才起作用? - Why does this code only work when run from inside Visual Studio but not otherwise? 为什么简单的ApplicationSetting PropertyBinding for Form在C#中不起作用? - Why does a simple ApplicationSetting PropertyBinding for a Form does not work in C#? 为什么此代码仅在第二次运行时才有效? - Why does this code only work the second time it is run? WinForms - 为什么每次在Visual Studio中打开它时C#表单都会运行SQL? - WinForms - why does C# form run the SQL in it every time I open it in Visual Studio? 为什么我写同样的算法时c#中的代码与c中的代码不同? - Why does the code in c# differs from the code in c when I write the same algorithm?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM