1

我创建了一个控制台应用程序。我想让标签(在表单上)显示我在控制台中键入的任何内容,但是当我运行表单时控制台会挂起。

代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace ConsoleApplication1
{
    class Program
    {
        Label a;
        static void Main(string[] args)
        {
            Form abc = new Form(); 
            Label a = new Label();
            a.Text = "nothing";
            abc.Controls.Add(a);
            Application.Run(abc);
            System.Threading.Thread t=new System.Threading.Thread(Program.lol);
            t.Start();


        }
        public static void lol()
        {
            Program p = new Program();
            string s = Console.ReadLine();
            p.a.Text = s;
            lol();
        }


    }
}
4

3 回答 3

3

Application.Run将阻塞直到表单关闭。所以你应该在一个单独的线程上调用它。

但是,您的 UI 将在该单独的线程上执行 - 并且您不能从 UI 线程以外的线程“触摸” UI 元素,因此在调用之后Console.ReadLine(),您需要使用Control.InvokeControl.BeginInvoke在 UI 中进行更改.

此外,您当前正在声明一个名为的局部变量a,但从未为Program.a.

这是一个完整的版本:

using System;
using System.Threading;
using System.Windows.Forms;

class Program
{
    private Program()
    {
        // Actual form is created in Start...
    }

    private void StartAndLoop()
    {
        Label label = new Label { Text = "Nothing" };
        Form form = new Form { Controls = { label } };
        new Thread(() => Application.Run(form)).Start();
        // TODO: We have a race condition here, as if we
        // read a line before the form has been fully realized,
        // we could have problems...

        while (true)
        {
            string line = Console.ReadLine();
            Action updateText = () => label.Text = line;
            label.Invoke(updateText);
        }
   }

    static void Main(string[] args)
    {
        new Program().StartAndLoop();
    }
}
于 2013-01-07T07:09:50.660 回答
3

您的代码中有很多问题,我不会包括命名选择。

  • Application.Run正在阻塞。Form在您关闭之前,您的其余代码不会被调用。

  • 您正在递归调用lol(),我不建议这样做。请改用while循环。

  • 您正在尝试Label从与创建控件的线程不同的线程中设置 a 的文本。您将需要使用Invoke或类似的方法。

这是您的代码可能如何的完整示例。我试图修改尽可能少的东西。

class Program
{
    static Label a;

    static void Main(string[] args)
    {
        var t = new Thread(ExecuteForm);
        t.Start();
        lol();
    }

    static void lol()
    {
        var s = Console.ReadLine();
        a.Invoke(new Action(() => a.Text = s));
        lol();
    }

    public static void ExecuteForm()
    {
        var abc = new Form();
        a = new Label();
        a.Text = "nothing";
        abc.Controls.Add(a);
        Application.Run(abc);
    }
}
于 2013-01-07T07:10:47.240 回答
2

在创建新的Thread. 这意味着您的程序在退出Thread之前永远不会真正创建新的。Form

你需要使用

System.Threading.Thread t = new System.Threading.Thread(Program.lol);
t.Start();
Application.Run(abc);
于 2013-01-07T07:05:15.107 回答