【问题标题】:Cleanest way to update user on thread status in multithreaded console application在多线程控制台应用程序中更新用户线程状态的最简洁方法
【发布时间】:2023-04-10 00:55:02
【问题描述】:

我有一个最近制作的多线程控制台应用程序。我希望我可以在新的控制台窗口中打开线程,但根据this article,这样做是不可能/不建议的。

我有以下几点:

do
{
      selection = DisplayMenu();

      switch (selection)
      {
          case 1:
              Thread thread1 = new Thread(() => Method1(param1, param2, param3));
              thread1.Start();
              break;
          case 2:
              Thread thread2 = new Thread(() => Method2(param1, param2, param3));
              thread2.Start();
              break;
          default:
               break;
       }      
} while (selection != 3);

Method1 和 Method2 都有 Console.WriteLine() 调用,向控制台窗口显示消息,向用户指示已完成的步骤、当前正在运行的步骤等。一切正常,除了当 @987654326 @ 在第一个线程运行后显示,它有点被推到顶部,因为 Console 记录 switch 语句中的方法所做的,因此我最初想将线程卸载到另一个控制台窗口.有什么建议吗?

更新

这就是DisplayMenu() 所做的:

public static int DisplayMenu()
{
    int selection = 0;

    Console.WriteLine("What do you want to do?");
    Console.WriteLine("[1] X");
    Console.WriteLine("[2] Y");
    Console.WriteLine("[3] QUIT");
    Console.Write("Selection: ");
    selection = Convert.ToInt32(Console.ReadLine());
    Console.WriteLine();

    return selection ;
}

更新

根据接受的答案,我现在正尝试将我的 Console.WriteLine() 调用路由到 Windows 窗体。我已将所有需要的依赖项和一个 Windows 窗体添加到我的控制台项目中。这是我目前所拥有的。

public static void WorkToDo()
{
    MyCustomObj myObj = new MyCustomObject();

    var form = new OutputForm();
    TextBox tb = new TextBox();
    form.Controls.Add(tb);
    form.Show(); //Code does not progress until window is closed

    if (MyCustomObject.Validate())
    {
        tb.Text += "Sent from Console App!"; //This was previously my Console.WriteLine() call.

似乎我无法流式传输到TextBox,因为该进程现在正在运行表单,而不是控制台应用程序中的其余代码。

【问题讨论】:

  • 什么是DisplayMenu?
  • @EZI 请查看更新。
  • 如果你需要这么复杂的控制台系统,你可能想看看将光标设置到窗口底部并在那里输出状态数据,然后将光标重置回窗口的主要部分对于其他一切。锁定同步对象以保持一次只有一个进程写入窗口。如果需要,有一些方法可以打开更多控制台窗口。

标签: c# multithreading user-interface logging console-application


【解决方案1】:

为什么需要这样做?

如果您不需要调试第二个线程/控制台或共享资源,您可以使用System.Diagnostics.Process.Start("*.exe"); 启动额外的控制台窗口,但我猜这不是您想要的?

您最好使用具有多个窗口的 GUI(例如 WPF 或 Windows 窗体),一个用于日志记录,另一个用于用户输入?或者可能记录到文件?

可以有一个子进程托管另一个控制台窗口。这里有详细说明: http://www.codeproject.com/Articles/13368/Multiple-consoles-for-a-single-application

创建一个 windows 窗体项目并使用 GUI 工具添加文本框等。请参阅https://msdn.microsoft.com/en-us/library/dd492132.aspx 了解更多信息。 然后像这样编辑表单后面的代码:

using System.Windows.Forms;

namespace StreamTextExample
{
    using System.ComponentModel;
    using System.Threading;

    internal sealed partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, System.EventArgs e)
        {
            var timer = new BackgroundWorker();
            timer.DoWork += DoWork;
            timer.RunWorkerAsync();
        }

        private void DoWork(object sender, DoWorkEventArgs doWorkEventArgs)
        {
            for (var i = 0; i < 10; ++i)
            {
                var del = new AddText(AddTextCallback);
                Invoke(del, string.Format("{0} seconds have passed.\r\n", i));

                Thread.Sleep(1000);
            }
        }

        private void AddTextCallback(string value)
        {
            textBox1.Text += value;
        }

        private delegate void AddText(string value);
    }
}

给定一个按钮 (button1) 和一个文本框 (textBox1),这会将自按下 button1 以来经过的秒数(最多 9 个)添加到文本框。

【讨论】:

  • 此外,这并不容易的原因是每个进程只有一个标准流(输入、输出和错误)。
  • William,我接受您对使用 Windows 窗体的建议的回答。我目前正在尝试启动一个 Windows 窗体窗口并将文本流式传输到那里。您能否提供有关如何执行此操作的任何建议?
  • 我已经编辑了我的答案以包含一个使用 Windows 窗体的示例。如果您愿意,我可以添加其他说明
  • @WilliamMoore 我已经在我的控制台应用程序中添加了一个 Windows 窗体,现在我只是想直接写给它。这可能吗? var form = new OutputForm(); TextBox tb = new TextBox(); form.Controls.Add(tb); form.Show(); //Gets stuck here tb.Text += "write to textbox instead of console";
  • 您是否初始化了文本框的.Text 属性。您对文本框的第一次使用必须是这样的:TextBox tb = new TextBox(); tb.Text = ""; // Add text box...then use += 此外,如果您从创建它的线程的另一个线程访问文本框,您必须使用委托回调(如我上面显示的那样)。跨度>
猜你喜欢
  • 1970-01-01
  • 2011-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-07
相关资源
最近更新 更多