在多线程控制台应用程序

时间:2015-07-13 22:19:57

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

我有一个我最近制作多线程的控制台应用程序。我的希望是我可以在新的控制台窗口中打开线程,但根据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);

Method1Method2都有Console.WriteLine()次调用,向控制台窗口显示消息,向用户显示已完成的步骤,当前正在运行的步骤等。一切正常,但事实上,当第一个线程运行后显示DisplayMenu()时,由于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,因为该进程现在正在运行表单,而不是控制台应用程序中的其余代码。

1 个答案:

答案 0 :(得分:2)

为什么需要这样做?

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

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

可以让子进程托管另一个控制台窗口。这在此详述: 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),这将把按钮1按下后的秒数(最多9个)添加到文本框中。