【问题标题】:Update a form after Application.Run()在 Application.Run() 之后更新表单
【发布时间】:2014-01-28 15:52:38
【问题描述】:

这是我想做的事

// pseudo code
Application.EnableVisualStyles(); 
Application.SetCompatibleTextRenderingDefault(false); 
Form1 myForm = new Form1();
Application.Run(myForm); 
while(true)
{
    string a = readline();
}
form1.show(a)

换句话说,我需要表单始终显示输入。但上面的代码将在“Application.Run(myForm);”之后停止。我不在 form1 类中编写此类代码的原因是代码的主要部分是在用 F# 编写的机器学习引擎上运行的,并且因为 F# 没有好的视觉设计器。所以我试图创建一个简单的 form1.dll,并用它来绘制随时间变化的结果。 所以我的问题是我只能初始化表单,但我不能随着时间的推移更新它。 任何提示将不胜感激。

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    您正尝试同时做 2 件事,因此您的应用程序应该通过使用 2 个线程来反映这一点。接下来Form的Show()方法不接受字符串,所以需要自己实现方法。

    这是一个 C# 2.0 WinForms 解决方案。程序运行线程并处理控制台输入:

    static class Program
    {
        [STAThread]
        private static void Main()
        {
            // Run form in separate thread
            var runner = new FormRunner();
            var thread = new Thread(runner.Start) {IsBackground = false};
            thread.Start();
    
            // Process console input
            while (true)
            {
                string a = Console.ReadLine();
                runner.Display(a);
                if (a.Equals("exit")) break;
            }
            runner.Stop();
        }
    }
    

    FormRunner 负责线程调用:

    internal class FormRunner
    {
        internal Form1 form = new Form1();
    
        internal void Start()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(form);
        }
    
        private delegate void StopDelegate();
    
        public void Stop()
        {
            if (form.InvokeRequired)
            {
                form.Invoke(new StopDelegate(Stop));
                return;
            }
            form.Close();
        }
    
        private delegate void DisplayDelegate(string s);
    
        public void Display(string s)
        {
            if (form.InvokeRequired)
            {
                form.Invoke(new DisplayDelegate(form.Display), new[] {s});
            }
        }
    }
    

    Form1 只需要显示一些东西:

        public void Display(string s)
        {
            textBox1.Multiline = true;
            textBox1.Text += s;
            textBox1.Text += Environment.NewLine;
        }
    

    【讨论】:

    • +1;一个问题:新线程的ApartmentState如何保证是STA?不需要显式设置吗?
    • 你说得对,默认是 MTA。您可以通过thread.SetApartmentState(ApartmentState.STA); 设置线程状态
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-07
    相关资源
    最近更新 更多