几天来,我一直在试图弄清楚如何使用make console更新文本框作为其执行。我得出的结论是,线程对于同时运行表单和控制台进程是绝对必要的。过程本身是独立的程序,所以我使用标准输出来获取信息,如果我不需要它来更新文本框作为它的工作,这将是很好的,但问题是它只会在执行过程后更新尽管我实际上正在使用多线程。文本框只在其他线程完成后更新
正在委托运行过程和处理输出,以及串,我使用的线程和锁之间交换信息功能的开始:
private static readonly object _locker = new object();
volatile string exchange = "";
delegate void CallDelegate(string filename);
继承人的函数本身:
public void CallConsole(string filename)
{
Thread.CurrentThread.Name = "ProccessThread";
Thread.CurrentThread.IsBackground = false;
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
p.StartInfo.FileName = filename;
if (checkBox1.Checked)
p.StartInfo.CreateNoWindow = true;
string output;
p.Start();
while (!p.HasExited)
{
lock (_locker)
{
output = p.StandardError.ReadToEnd();
if (output.Length != 0)
{
exchange = output;
Thread.Sleep(100);
MessageBox.Show(output);
}
output = p.StandardOutput.ReadToEnd();
exchange = output;
System.Threading.Thread.Sleep(100);
}
}
}
而这里的程序button_click后执行
private void button1_Click_1(object sender, EventArgs e)
{
textBox2.Text = "";
//Thread.CurrentThread.Name = "Main";
CallDelegate call = new CallDelegate (CallConsole);
IAsyncResult tag = call.BeginInvoke(textBox1.Text, null, null);
button1.IsAccessible = false;
while (!tag.IsCompleted)
{
string temp = "";
lock (_locker)
{
Thread.Sleep(50);
if (exchange.Length != 0)
{
temp = exchange;
exchange = "";
}
}
if (temp.Length != 0)
textBox2.Text = textBox2.Text + temp;
}
call.EndInvoke(tag);
button1.IsAccessible = true;
}
注: TextBox1的是文件路径 TextBox2中是只读的多行TextBox
为什么只有CallConsole后的更新做任何想法?
我认为Jon Skeet是发生在SO和C#上的最好的事情之一。 – Burimi 2012-01-03 14:48:59