在多线程控制台应用程序中更新用户线程状态的最简洁方法
Cleanest way to update user on thread status in multithreaded console application
我最近将一个控制台应用程序设为多线程。我希望我可以在新控制台 window 中打开线程,但根据 this article,做这样的事情并不是真的 possible/advisable。
我有以下内容:
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()
向控制台显示消息的调用 window 向用户指示已完成的步骤,当前正在执行的步骤 运行ning 等一切正常,除了在第一个线程 运行 之后显示 DisplayMenu()
时,由于 Console
日志记录,它有点被推到顶部switch
语句中的方法确实如此,因此我最初想将线程卸载到另一个控制台 window。有什么建议吗?
更新
这就是 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
,因为该进程现在正在 运行 表单而不是控制台应用程序中的其余代码。
为什么需要这样做?
如果您不需要调试第二个 thread/console 或共享资源,您可以使用 System.Diagnostics.Process.Start("*.exe");
启动额外的控制台 window,但我猜这不是你想要的想要?
您最好使用 WPF 或 Windows 具有多个 windows 表单的 GUI,一个用于日志记录,另一个用于用户输入?或者可能登录到文件?
可以让子进程托管另一个控制台 window。这里有详细说明:
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 秒)添加到文本框。
我最近将一个控制台应用程序设为多线程。我希望我可以在新控制台 window 中打开线程,但根据 this article,做这样的事情并不是真的 possible/advisable。
我有以下内容:
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()
向控制台显示消息的调用 window 向用户指示已完成的步骤,当前正在执行的步骤 运行ning 等一切正常,除了在第一个线程 运行 之后显示 DisplayMenu()
时,由于 Console
日志记录,它有点被推到顶部switch
语句中的方法确实如此,因此我最初想将线程卸载到另一个控制台 window。有什么建议吗?
更新
这就是 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
,因为该进程现在正在 运行 表单而不是控制台应用程序中的其余代码。
为什么需要这样做?
如果您不需要调试第二个 thread/console 或共享资源,您可以使用 System.Diagnostics.Process.Start("*.exe");
启动额外的控制台 window,但我猜这不是你想要的想要?
您最好使用 WPF 或 Windows 具有多个 windows 表单的 GUI,一个用于日志记录,另一个用于用户输入?或者可能登录到文件?
可以让子进程托管另一个控制台 window。这里有详细说明: 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 秒)添加到文本框。