在Windows窗体应用程序中永远循环

我正在使用Visual C#sand我使用的是Windows窗体而不是控制台应用程序。 因此,我不是在Main()中工作,而是在Form File中工作。 我对C#也很陌生,很抱歉,如果我的一些问题是愚蠢的。

我基本上需要做的是当我的程序启动时我需要它来永远循环。 由于我没有Main(),我会把这段代码放在哪里? 我把它放在具有InitializeComponent()的函数中吗? 我需要在程序启动后立即启动循环。 但是,我需要在循环之前首先声明一些变量。 所以基本上我需要声明变量然后开始无限循环。 变量是全局的。

其次,当用户按下按钮时,我需要无限循环中断。 我该怎么办? 我正在考虑以下几点:

while (buttonIsPressed == false) { //do whatever I need to do } 

但是,我意识到按钮的function永远不会被调用,因为我被困在那个循环中。 如果由于处于无限循环中而从未到达按钮的function,我无法从按钮的function设置变量。 有任何想法吗? 我正在考虑线程,但我绝对没有线程经验,所以有点不愿意尝试它。


另外,来自评论:

聊天应用程序。 程序启动时我需要它继续听。 但是,当用户单击“连接”时,它会停止侦听,而是启动连接

我正在创建一个聊天客户端。 所以基本上当我的程序启动时,我需要它继续听。 但是,当用户单击“连接”时,它需要停止侦听,而是启动连接

对于那些来自(完全)不同背景的人来说,这是一个自然的问题。

编程Windows窗体应用程序是事件驱动的。 当Windows窗体应用程序启动时,会加载一个窗体(检查Program.cs文件),并且有一个隐藏的主循环,专注于程序中的重要事项。

您不需要在Main循环中放置任何内容来响应事件(如按钮单击事件)。 您只需通过为Button的Click事件创建事件处理程序来处理按钮单击事件。 您可以使用设计器或在代码中手动执行此操作。

当您创建一个处理事件的方法时(因此该方法称为事件处理程序),在引发/触发事件时会自动调用它。 例如,当用户单击按钮时,将调用表单上Button的Click事件的方法处理程序。

此MSDN主题包含您需要的所有信息: 在Windows窗体中创建事件处理程序 。 如果您需要更多说明,请询问! 🙂

更新:像上面一样创建一个事件处理程序,并在Form_Loaded事件处理程序中创建一个循环。 一定要调用Application.DoEvents(); 循环内。 这样就可以处理按钮单击的事件处理程序(在处理程序中添加代码以修改将使循环条件为false以取消循环的布尔值)。

更新2:为了使这个答案更加完整,我提到你还应该考虑在一个新线程上运行循环,而不是在UI上运行循环(因此避免需要使用DoEvents,它的负面效果正如我的同行指出的那样)。 以下示例显示如何创建线程并在按钮上取消它:

  System.Threading.Thread t; private void Form1_Load(object sender, EventArgs e) { //create and start a new thread in the load event. //passing it a method to be run on the new thread. t = new System.Threading.Thread(DoThisAllTheTime); t.Start(); } public void DoThisAllTheTime() { while (true) { //you need to use Invoke because the new thread can't access the UI elements directly MethodInvoker mi = delegate() { this.Text = DateTime.Now.ToString(); }; this.Invoke(mi); } } private void button1_Click(object sender, EventArgs e) { //stop the thread. t.Suspend(); } 

最后,考虑使用BackgroundWorker ,它封装了为您创建和管理线程。

为什么你需要它来永远循环?

这里有趣的是,无论如何你的程序都会这样做; 它被称为消息循环。 当用户与其交互时(点击按钮等),它会不断接收消息

你究竟想做什么? 肯定已经有了一个可以满足您需求的构造,无论是Timer , BackgroundWorker等。

要侦听TCP套接字,有TcpListener类。 您可以启动一个线程供TCP侦听器运行。

如果您需要表单来响应按钮单击,则循环必须在主线程以外的线程中进行, BackgroundWorker将适合您。

您似乎正在尝试创建聊天客户端(有关示例代码,请参阅此示例 )。 对于长时间运行的并行执行,我建议您创建并启动一个主体是您提到的while循环的线程 。

你必须要理解的关键是将有两个执行线程。 一个是UI线程,负责绘制表单并对按钮点击等事件做出反应(注意:当用户与UI交互时,这将永远循环响应事件)。 另一个线程是循环后台线程,您将创建它以侦听网络信息。 上面引用的示例聊天客户端创建线程以响应单击某个按钮,但由于您希望尽快开始循环,我建议您创建并启动线程以响应Load事件 (只需双击表单)在Visual Studio的设计器模式下创建相应的加载事件处理程序)。

棘手的部分是当您想要从后台线程更新UI元素时。 要做到这一点,没有例外,您必须封送对UI线程的方法调用。 这可以使用任何控件上的invoke方法来完成(再次参见引用的示例代码)。

要打破循环,可以在按钮单击事件处理程序中将buttonPressed标志设置为false。 此事件处理程序将在UI线程上运行,但共享标志将使后台线程在下次迭代到条件语句时突破其循环。