WPF追加文本块UI线程,但大量的WinForms不? [英] WPF append text blocks UI thread heavily but WinForms doesn't?

查看:106
本文介绍了WPF追加文本块UI线程,但大量的WinForms不?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我将我的应用程序从的WinForms到WPF,和我很高兴与大多数的新功能。然而,有一个主要的障碍我已经打了。当我附上的文字不断地到我的文本框,UI线程变得如此堵住了,我不能做什么,但看它追加文本!我需要能够切换标签在我的标签控件,点击按钮等等等等奇怪的是,我绝对没有在UI线程的WinForms放缓!

I recently converted my application from WinForms to WPF, and I'm happy with most of the new features. However, there is a major stumbling block I've hit. When I append text constantly to my textboxes, the UI thread becomes so blocked up that I can't do anything but watch it append text! I need to be able to switch tabs in my tab control, click buttons, etc etc. The strange thing is that I have absolutely no slowdown in the UI thread in WinForms!

所以,这里是我的应用程序的一些背景:它运行其它程序作为一个动作队列的一部分,吐出这些进程的输出和错误分成两个独立的文本框,以及日志文本框(这些是影响文本框)。在低输出过程中,有没有放缓,但是当我使用像SVN签和文件复制过程中,我得到这么多的文本输出一次,所有它能做的就是追加文本。

So, here's a little background on my application: it runs other processes as part of an "action queue", and spits out those process's stdout and stderr into two separate textboxes, as well as the log textbox (these are the impacted textboxes). On low output processes, there is no slowdown, but when I use processes like SVN checkout and file copying, I get so much text output at once that all it can do is append text.

下面是我的打印代码:


public void PrintOutput(String s)
{
    String text = s + Environment.NewLine;
    Window.Dispatcher.Invoke(new StringArgDelegate(Window.PrintOutput), text);
    Debug.Log("d " + text);
}

public void PrintLog(String s)
{
    ClearLogButtonEnabled = true;
    String text = s + Environment.NewLine;
    Window.Dispatcher.Invoke(new StringArgDelegate(Window.PrintLog), text);
}

和匹配的隐藏代码:


public void PrintOutput(String s)
{
     outputTextBox.AppendText(s);
     outputTextBox.ScrollToEnd();
     if (!clearOutputButton.IsEnabled) clearOutputButton.IsEnabled = true;
}

public void PrintLog(String s)
{
     logTextBox.AppendText(s);
     logTextBox.ScrollToEnd();
}



就这样我没有得到一堆指责,说我' ]丢UI线程对我的工作为好,这里是我的用于启动的独立的工作线程的代码:


Thread actionThread = new Thread(new ThreadStart(ActionManager.Instance().ExecuteActions));
actionThread.Name = "Action Manager Work Thread";
actionThread.Start();

这是处理启动,运行,并清理所有辅助进程的线程。这些过程使用上面打印的标准输出/标准错误输出打印的方法。 !另外,每个进程都有自己的线程

This is the thread that handles starting, running, and cleaning up of all the auxiliary processes. These processes use the print methods shown above to print their stdout/stderr output. Additionally, each process gets its own thread!


Thread procThread = new Thread(new ThreadStart(StartProcess));
procThread.Name = action.Name + "_" + Guid.NewGuid();
procThread.Start();



我担心的是,WPF在某种程度上是在调用速度较慢,而且我搞砸。我投入了大量的工作切换到从的WinForms此应用程序WPF,因此如果任何人知道为什么我会在打印速度会得到这样一个庞大的经济放缓请让我知道!

My worry is that WPF is slower at Invokes in some way and that I'm screwed. I put a lot of work into switching this application to WPF from WinForms, so if anyone knows why I'd be getting such a massive slowdown in print speeds please let me know!

编辑:

我还要补充一点,我使用的是的RichTextBox ,而不是文本框,而我需要的的RichTextBox 来加粗某些文本的功能。如果有一种方法提供粗体文字一个不太繁琐的TextBox类请让我知道。

I should also add that I am using a RichTextBox, not a TextBox, and that I need the features of the RichTextBox to bold certain text. If there is a way to provide bold text with a less cumbersome TextBox class please let me know.

推荐答案

在WPF 的RichTextBox 是一个非常重量级的UI元素,因为它不仅可以让内容丰富的的 WPF文档,但它也有编辑功能

The WPF RichTextBox is a very heavy-weight UI element, because it not only allows rich content in the form of a WPF Document, but it also has editing capabilities.

你真正需要在这种情况下,是的 FlowDocumentScrollViewer

What you really need in this case is a FlowDocumentScrollViewer.

这是我的日志查看器样品,它采用小适应一个 FlowDocumentScrollViewer 代替的ItemsControl 。它的优点是,这个UI元素使文字选择和复制,同时保留您所需要的丰富文本功能:

This is a small adaptation of my Log Viewer Sample, which uses a FlowDocumentScrollViewer instead of an ItemsControl. The advantage is that this UI element allows text selection and copying, while retaining the Rich Text capabilities you need:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <FlowDocumentScrollViewer Document="{Binding}"/>
</Window>

代码背后:

public partial class MainWindow : Window
    {
        private System.Random random;
        private string TestData = "Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum";
        private List<string> words;
        private int maxword;
        private int index;

        private FlowDocument doc;
        private Paragraph paragraph;

        public MainWindow()
        {
            InitializeComponent();

            DataContext = doc = new FlowDocument();

            doc.Blocks.Add(paragraph = new Paragraph());

            Task.Factory.StartNew(AddDataLoop);
        }

        private void AddDataLoop()
        {
            random = new Random();
            words = TestData.Split(' ').ToList();
            maxword = words.Count - 1;

            while (true)
            {
                Thread.Sleep(10);
                Dispatcher.BeginInvoke((Action) (AddRandomEntry));
            }
        }

        private void AddRandomEntry()
        {
            var run = new Run(string.Join(" ", Enumerable.Range(5, random.Next(10, 50))
                                                         .Select(x => words[random.Next(0, maxword)])));

            var isBold = random.Next(1, 10) > 5;

            if (isBold)
                paragraph.Inlines.Add(new Bold(run));
            else
                paragraph.Inlines.Add(run);

            paragraph.Inlines.Add(new LineBreak());
        }
    }



结果:

Result:


  • 这再一次证明,但绝对什么您可以在无法用WPF实现的WinForms实现,反之则相反不能说,很明显。这使的WinForms一个几乎过时的技术,它字面替换被更新的,更有能力的人。

  • Once again, this proves that there's absolutely nothing you can achieve in winforms that can't be achieved with WPF, whereas the opposite can't be said, obviously. This makes winforms a practically obsolete technology that is literally replaced by newer, more capable ones.

的通知我放在 10毫秒每一个新的条目之间的延迟。这几乎是实时的,而UI不显示任何放缓或闪烁或任何形式的质量下降。

Notice that I placed a 10 millisecond delay between each new entry. This is practically real time, and the UI does not show any slowing down or flickering or any quality degradation of any kind.

与我的其他例子,通知大多数后面的代码是从字面上样板生成随机文本,代码的唯一相关的行 paragraph.Inlines.Add(...)

As with my other example, notice that most of the code behind is literally boilerplate to generate random text, the only relevant lines of code are paragraph.Inlines.Add(...).

WPF岩 - 简单地复制和粘贴我的代码在文件 - >新建项目 - > WPF应用程序,并看到自己的成果。

WPF Rocks. - simply copy and paste my code in a File -> New Project -> WPF Application and see the results for yourself.

让我知道如果你需要进一步的帮助。

Let me know if you need further help.

这篇关于WPF追加文本块UI线程,但大量的WinForms不?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆