Richtextbox.invoke,C#,表单仍然挂起

发布于 2024-07-16 10:29:37 字数 1202 浏览 4 评论 0原文

我已经编写了 ac# 应用程序来运行外部程序,并将其输出重定向到我的表单中的 Richtextbox。 我已经使用以下设置

p1.StartInfo.RedirectStandardOutput = true;
p1.OutputDataReceived += new DataReceivedEventHandler(outputreceived);

和在outputreceived事件中

void outputreceived(object sender, DataReceivedEventArgs e)
{
  if (!string.IsNullOrEmpty(e.Data))
  {
    richTextBox1.Invoke(new UpdateOutputCallback(this.updateoutput),
                        new object[] { e.Data });
  }
}

void updateoutput(string text)
{
  int len = text.Length;
  int start = richTextBox1.Text.Length;
  richTextBox1.Text += text + Environment.NewLine;
  richTextBox1.Select(start, len);
  richTextBox1.SelectionColor = System.Drawing.Color.White;
  richTextBox1.Select(richTextBox1.Text.Length, 0);
  richTextBox1.ScrollToCaret();
}

创建了该进程现在,虽然它正在工作,但是如果应用程序的输出很大,那么包含文本框的主窗体就会挂起。 我认为每次调用都会导致表单的重新绘制,这种情况经常发生。 有没有其他选择,以便我可以看到文本框的更新,并保持表单完全活动?


更新:

我想我得到了答案,当我应该使用Invoke时,我使用了BeginInvoke


更新 1:

我尝试了 BeginInvoke 和 Suspendlayout,但它没有给我所需的功能,发生的情况是该进程已将所有标准输出返回到字符串,但负责更新文本的线程正在花费自己的时间打印数据。 我可以对它做点什么吗?

I've written a c# application to run an external program and i've redirectet it's output to a richtextbox in my form. I've created the process using the following settings

p1.StartInfo.RedirectStandardOutput = true;
p1.OutputDataReceived += new DataReceivedEventHandler(outputreceived);

and in the outputreceived event

void outputreceived(object sender, DataReceivedEventArgs e)
{
  if (!string.IsNullOrEmpty(e.Data))
  {
    richTextBox1.Invoke(new UpdateOutputCallback(this.updateoutput),
                        new object[] { e.Data });
  }
}

void updateoutput(string text)
{
  int len = text.Length;
  int start = richTextBox1.Text.Length;
  richTextBox1.Text += text + Environment.NewLine;
  richTextBox1.Select(start, len);
  richTextBox1.SelectionColor = System.Drawing.Color.White;
  richTextBox1.Select(richTextBox1.Text.Length, 0);
  richTextBox1.ScrollToCaret();
}

Now the thing is though it is working, but my main form which contains the textbox, hangs if the output is huge from the application. I think each time the invoke call leads to repainting of the form, which happens very frequently. Is there any alternative so that i can see the updates to the textbox as they happen and also keep the form completely active?


Update:

I think I got my answer, I used BeginInvoke when I should have used Invoke.


Update 1:

I tried both BeginInvoke and Suspendlayout but it is not giving me the desired functionality, what happens is that the process has returened all the standardoutput to the string, but the thread which is responsible for updating the text is taking it's own time to print the data. Can i do any thing to it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

蒲公英的约定 2024-07-23 10:29:37

既然您已经解决了您的问题,我只想指出,如果您使用 rtb.AppendText (而不是 Text += ...),速度会更快并且使用 pinvoke 滚动到底部:

private const int WM_VSCROLL = 0x115;
private const int SB_BOTTOM = 7;

[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam,
IntPtr lParam);

// ...
// Scroll to the bottom, but don't move the caret position.
SendMessage(rtb.Handle, WM_VSCROLL, (IntPtr) SB_BOTTOM, IntPtr.Zero);

Since you've already solved your problem, I'll just note that it will be faster if you use rtb.AppendText (instead of Text += ...) and use pinvoke to scroll to the bottom:

private const int WM_VSCROLL = 0x115;
private const int SB_BOTTOM = 7;

[DllImport("user32.dll", CharSet=CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam,
IntPtr lParam);

// ...
// Scroll to the bottom, but don't move the caret position.
SendMessage(rtb.Handle, WM_VSCROLL, (IntPtr) SB_BOTTOM, IntPtr.Zero);
老街孤人 2024-07-23 10:29:37

您可能想尝试

richTextBox1.BeginInvoke() 

而不是

richTextBox1.Invoke()

至少会使调用异步。 仍然不确定这是否会导致 UI 线程在绘制更新时锁定。

You might want to try

richTextBox1.BeginInvoke() 

rather than

richTextBox1.Invoke()

That will at least make the call Asynchronous. Still not sure if that will cause the UI thread to lock while the updates are being painted.

墨落成白 2024-07-23 10:29:37

尝试暂停并恢复 richTextBox1 的布局

    void updateoutput(string text)
    {
        try
        {
            richTextBox1.SuspendLayout();

            int len = text.Length;
            int start = richTextBox1.Text.Length;
            richTextBox1.Text += text + Environment.NewLine;
            richTextBox1.Select(start, len);
            richTextBox1.SelectionColor = Color.White;
            richTextBox1.Select(richTextBox1.Text.Length, 0);
            richTextBox1.ScrollToCaret();
        }
        finally
        {
            richTextBox1.ResumeLayout();
        }
    }

是否有任何替代方案,以便我可以看到文本框的更新,并保持表单完全活动?

我认为您应该使用 Debug.Print 来查看发生的情况。

Try to suspend and resume layout of richTextBox1

    void updateoutput(string text)
    {
        try
        {
            richTextBox1.SuspendLayout();

            int len = text.Length;
            int start = richTextBox1.Text.Length;
            richTextBox1.Text += text + Environment.NewLine;
            richTextBox1.Select(start, len);
            richTextBox1.SelectionColor = Color.White;
            richTextBox1.Select(richTextBox1.Text.Length, 0);
            richTextBox1.ScrollToCaret();
        }
        finally
        {
            richTextBox1.ResumeLayout();
        }
    }

Is there any alternative so that i can see the updates to the textbox as they happen and also keep the form completely active?

I think you should use Debug.Print to view what's going on instead.

寄与心 2024-07-23 10:29:37

这是一篇旧帖子,但也许有人仍然像我一样在寻找它。

您也可以这样做,例如“for(writeToTextbox % 10 == 0)”,然后调用。
在这种情况下,它只会每 10 次更新一次。

更新:抱歉拼写错误! (wirte -> write)并感谢“HaveNoDisplayName”向我展示它!

It is an old post, but maybe somebody still looking for it like I did.

You also can do, like "for(writeToTextbox % 10 == 0)" then invoke.
In this case it will be updated only every 10 times.

UPDATE: sorry for the misspelling! (wirte -> write) and thanks for "HaveNoDisplayName" to show it to me!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文