我正在开发一个基于 CLI 的控制台应用程序,其中大部分繁重的工作都是通过小程序、脚本和命令行指令执行的。
然而,一些小程序确实使用了 WinForms,并且这个功能已经被添加并且工作得相当好,只要通过“Form.ShowDialog()”(而不是仅仅“Form.Show()”)激活表单。
我认为这是因为创建的表单与基本(以控制台为中心的)应用程序共享消息传递线程,并且两者不能很好地协同工作。
经过哈希处理后,我们确定我们不想在表单打开时暂停 CLI(尤其是因为我们希望能够打开多个独立的表单),所以我的猜测是我需要实例化新形式在他们自己的线程中,但这个想法在尖叫“太复杂了!” 对我来说,所以我想知道是否有更有效/简化的方法来实现这一目标?
我能否以某种方式产生一个与基础线程分开的单个线程,所有表单都可以在该线程上共享(就像在标准的 Windows 窗体应用程序中一样?)如果是这样,我将如何实现它?
目前,已经有三个线程启动并运行 -->
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] 删除。
我来说两句