C# 如何使用一些 WinForm 元素最好地管理基于控制台的 CLI 应用程序上的线程

网络专家

我正在开发一个基于 CLI 的控制台应用程序,其中大部分繁重的工作都是通过小程序、脚本和命令行指令执行的。

然而,一些小程序确实使用了 WinForms,并且这个功能已经被添加并且工作得相当好,只要通过“Form.ShowDialog()”(而不是仅仅“Form.Show()”)激活表单。

我认为这是因为创建的表单与基本(以控制台为中心的)应用程序共享消息传递线程,并且两者不能很好地协同工作。

经过哈希处理后,我们确定我们不想在表单打开时暂停 CLI(尤其是因为我们希望能够打开多个独立的表单),所以我的猜测是我需要实例化新形式在他们自己的线程中,但这个想法在尖叫“太复杂了!” 对我来说,所以我想知道是否有更有效/简化的方法来实现这一目标?

我能否以某种方式产生一个与基础线程分开的单个线程,所有表单都可以在该线程上共享(就像在标准的 Windows 窗体应用程序中一样?)如果是这样,我将如何实现它?

目前,已经有三个线程启动并运行 -->

  1. 最初执行 EXE 时获得的原始(基本)控制台线程。
  2. 一个等待 Console.KeyAvailable 并捕获/管理所有击键和输入解析的线程,以及提示显示和实例化调用的命令。
  3. 管理命令列表并处理出现在该列表中的任何新命令的线程(这些命令可以从键盘输入线程添加,也可以通过小程序或脚本添加)。

FWIW,“命令”只是实例化操作(运行小程序,访问内置函数等)的字符串。

当“退出”函数被调用时,它会终止键盘监听线程,然后释放命令执行线程(它正在运行),从而允许它退出并将控制权返回给操作系统。

目前,除了键盘线程上的一些偶尔缓慢的响应之外,一切都完全按预期工作,除非,如前所述,当我尝试通过 .Show 而不是 .ShowDialog 实例化 WinForm 时

任何见解,建议或指示将不胜感激!

另外:我在发布之前阅读了一些线程,同时寻找答案(即这个 ->如何从控制台应用程序运行 winform?)但他们似乎都假设控制台窗格将用作其本机目的(即Windows 控制台)作为独立的 CLI 界面被选择,所以我没有找到任何真正解决这个特定用例的东西,让我现在仍然有些茫然!(并且真的不想考虑必须编写底层管理引擎来为每个打开的表单生成/关闭独特的、独立的线程!)。

谢谢!

吉里·沃莱尼克

这是因为 Form.ShowDialog() 执行它自己的 runloop,但 Form.Show() 没有。您需要通过调用 Application.Run() 自己执行 runloop。

但是,您必须在线程之间建立某种通信。在以下示例中,我使用了 hiddenForm.BeginInvoke(),它将方法调用发布到应用程序的消息队列中。这是 hiddenForm 存在的唯一原因。

当然,您可以使用 Task、Thread 或任何适合您的方法来代替 BackgroundWorker。

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace ConsoleWithForms
{
    class Program
    {
        static BackgroundWorker worker;
        static MyForm hiddenForm; 

        static void Main(string[] args)
        {
            worker = new BackgroundWorker();
            worker.DoWork += DoWork;
            worker.RunWorkerAsync();

            Console.WriteLine("Type 'form' or 'quit'...");

            for (var quit = false; !quit;)
            {
                var line = Console.ReadLine().ToLower();
                switch (line)
                {
                    case "quit": quit = true; InvokeCommand("quit"); break;
                    case "form": InvokeCommand("form"); break;
                    default: break;
                }
            }
        }

        private static void DoWork(object sender, DoWorkEventArgs e)
        {
            Application.EnableVisualStyles();
            hiddenForm = new MyForm();
            hiddenForm.Show();
            hiddenForm.Hide();
            Application.Run();
        }

        private static void InvokeCommand(string command)
        {
            hiddenForm.BeginInvoke((Action)delegate {
                hiddenForm.PerformCommand(command);
            });
        }
    }

    class MyForm : Form
    {
        public MyForm()
        {
            Text = "MyForm";
            var button = new Button { Text = "New Form", AutoSize = true };
            button.Click += (sender, args) => { new MyForm().Show(); };
            Controls.Add(button);
        }

        public void PerformCommand(string command)
        {
            switch(command)
            {
                case "form": new MyForm().Show(); break;
                case "quit": Application.ExitThread(); break;
                default: break;
            }
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何在具有Windows应用程序输出类型的C#程序上显示控制台

来自分类Dev

如何在.NET 5.0控制台应用程序上的C#中检查Windows版本

来自分类Dev

如何在c ++ / CLI应用程序中显示控制台?

来自分类Dev

在C#winform应用程序上显示表中的数据

来自分类Dev

C#控制台应用程序上的转义按钮

来自分类Dev

使用CUI测试生成器测试Winform应用程序上的接受按钮

来自分类Dev

在已发布的Winform应用程序上使用Entity Framework时出错

来自分类Dev

使用全局变量将Winform重写为控制台应用程序

来自分类Dev

如何在Azure Webjob /控制台应用程序上获取当前路径

来自分类Dev

无法在控制台应用程序上使用QueueClient.OnMessage进行调试

来自分类Dev

如何绘制叠加窗口Winform应用程序C#

来自分类Dev

如何以管理员身份启动C#控制台应用程序

来自分类Dev

从控制台应用程序显示Winform的正确方法

来自分类Dev

通过控制台运行Winform应用程序

来自分类Dev

如何在C#中的Winform应用程序中设置combobox第一个元素

来自分类Dev

如何防止Firebase Web应用程序上的客户端控制台被黑客入侵?

来自分类Dev

如何在基于 Web 的实时应用程序中使用多线程,我可以获得一些场景吗

来自分类Dev

如何管理多线程C#应用程序

来自分类Dev

构建一个控制台应用程序文件资源管理器 C++

来自分类Dev

SlowCheetah在C#控制台应用程序上不起作用

来自分类Dev

如何测试基于Jline的控制台应用程序

来自分类Dev

如何从C#中的控制台应用程序运行Web应用程序

来自分类Dev

如何在C#应用程序上连接到SQL Server

来自分类Dev

C#.Net应用程序上的SQL错误,后端使用SQL Server 2008

来自分类Dev

.Net 控制台应用程序作为 CLI 命令

来自分类Dev

如何将 C# WinForm 应用程序和安装程序移植到 MacOS?

来自分类Dev

通过CLI包装在非托管C ++中的C#.NET Winform-需要线程吗?

来自分类Dev

多线程应用程序上的易失性C / C ++

来自分类Dev

多线程应用程序上的易失性C / C ++

Related 相关文章

  1. 1

    如何在具有Windows应用程序输出类型的C#程序上显示控制台

  2. 2

    如何在.NET 5.0控制台应用程序上的C#中检查Windows版本

  3. 3

    如何在c ++ / CLI应用程序中显示控制台?

  4. 4

    在C#winform应用程序上显示表中的数据

  5. 5

    C#控制台应用程序上的转义按钮

  6. 6

    使用CUI测试生成器测试Winform应用程序上的接受按钮

  7. 7

    在已发布的Winform应用程序上使用Entity Framework时出错

  8. 8

    使用全局变量将Winform重写为控制台应用程序

  9. 9

    如何在Azure Webjob /控制台应用程序上获取当前路径

  10. 10

    无法在控制台应用程序上使用QueueClient.OnMessage进行调试

  11. 11

    如何绘制叠加窗口Winform应用程序C#

  12. 12

    如何以管理员身份启动C#控制台应用程序

  13. 13

    从控制台应用程序显示Winform的正确方法

  14. 14

    通过控制台运行Winform应用程序

  15. 15

    如何在C#中的Winform应用程序中设置combobox第一个元素

  16. 16

    如何防止Firebase Web应用程序上的客户端控制台被黑客入侵?

  17. 17

    如何在基于 Web 的实时应用程序中使用多线程,我可以获得一些场景吗

  18. 18

    如何管理多线程C#应用程序

  19. 19

    构建一个控制台应用程序文件资源管理器 C++

  20. 20

    SlowCheetah在C#控制台应用程序上不起作用

  21. 21

    如何测试基于Jline的控制台应用程序

  22. 22

    如何从C#中的控制台应用程序运行Web应用程序

  23. 23

    如何在C#应用程序上连接到SQL Server

  24. 24

    C#.Net应用程序上的SQL错误,后端使用SQL Server 2008

  25. 25

    .Net 控制台应用程序作为 CLI 命令

  26. 26

    如何将 C# WinForm 应用程序和安装程序移植到 MacOS?

  27. 27

    通过CLI包装在非托管C ++中的C#.NET Winform-需要线程吗?

  28. 28

    多线程应用程序上的易失性C / C ++

  29. 29

    多线程应用程序上的易失性C / C ++

热门标签

归档