gpt4 book ai didi

c# - 文本框仅在其他线程完成后更新

转载 作者:太空宇宙 更新时间:2023-11-03 18:41:09 24 4
gpt4 key购买 nike

几天来,我一直在尝试弄清楚如何在执行时使用 make console update text-box。我得出结论,线程对于同时运行表单和控制台进程是绝对必要的。流程本身是独立程序,所以我使用标准输出从中获取信息,如果我不需要它在工作时更新文本框,那就太好了,但问题是它只在流程执行后更新尽管实际上我正在使用多线程。

开始为运行进程和处理输出的函数创建委托(delegate),以及我用于在线程和锁之间交换信息的字符串:

    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);
}
}
}

这里是按钮点击后程序的执行情况

    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 是只读的多行文本框

知道为什么它只在 CallConsole 完成后才更新吗?

最佳答案

一般问题:您在 button1_Click_1 中循环,有效地阻塞了 UI 线程。这会阻止处理其他事件 - 包括重绘等。

你不应该那样做;相反,如果您想轮询某些内容,请设置一个计时器来进行轮询,允许 UI 在“空闲”时间处理事件。

更紧迫的问题:您在未完成的进程中对读取器调用 ReadToEnd。这将(我相信)阻塞,直到该过程完成。 (在它完成之前,读者没有这样的“结束”。)这意味着你有一个线程持有锁并阻塞直到进程完成 - 然后你试图在界面线程。

我还建议从一开始就减少整个事情对轮询的依赖性 - 查看 Process 类上的事件,并尝试处理这些事件,而不是在单独的线程中阻塞。当其中一个事件发生时,您可以回发到 UI 线程(使用 Control.Invoke)来更新 UI...然后没有需要轮询。 p>

关于c# - 文本框仅在其他线程完成后更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8711689/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com