如何使用BeginInvoke从BackgroundWorker更新RichTextBox [英] How to update a RichTextBox from BackgroundWorker using BeginInvoke

查看:68
本文介绍了如何使用BeginInvoke从BackgroundWorker更新RichTextBox的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个小应用程序,该应用程序读取管道已降级的文件并将行写到RTB,突出显示某些列"中是否存在不允许的字符.效果很好……但是,用户需要一个进度条,并看到正在实时"运行的行,并且还可以在中途取消.

I have a small app that reads in a pipe delimted file and writes out lines to a RTB, highlighting if there are dissallowed characters in certain "columns". This is working perfectly...however, the Users want a progress bar and to see the lines being written "live" and also to be able to cancel mid-way through.

在阻止UI的同时,我有以下扩展方法用于写入RichTextBox,但这无法使用带有BeginInvoke的BackgroundWorker.

I have the following extension method that I have been using to write to a RichTextBox, while blocking the UI, but this fails using a BackgroundWorker with BeginInvoke.

失败是在查找文本的当前长度时.

The fail is when finding the current length of the text.

public static void AppendLine(this RichTextBox richTextBox, string text, List<Char> foundChars, List<int> columns)
        {
            var split = text.Trim().Split(new char[] { '|' });

            for (int i = 0; i < split.Count(); i++)
            {
                **var start = richTextBox.TextLength;**
                richTextBox.AppendText(split[i]);
                var end = richTextBox.TextLength;

                if (columns.Contains(i + 1))
                {
                    foreach (var foundChar in foundChars)
                    {
                        var current = start;

                        while (current > 0)
                        {
                            var position = richTextBox.Find(new char[] { foundChar }, current, end);
                            current = position + 1;
                            if (current > 0)
                            {
                                richTextBox.Select(position, 1);
                                richTextBox.SelectionColor = Color.Red;
                            }
                        }
                    }
                }
                richTextBox.SelectionLength = 0;
                richTextBox.SelectionColor = Color.Black;
            }
            richTextBox.AppendLine();
        }


private void UpdateResultsLine(string line, List<char> foundChars)
        {
            if (txtResults.InvokeRequired)
            {
                txtResults.BeginInvoke(new UpdateResultsLineDelegate(UpdateResultsLine), line, foundChars);
            }
            txtResults.AppendLine(line, foundChars, _fileType.ProcessColumns);
        }

但是,如果我以相同的方式调用所有这些扩展名,它们会起作用吗?

However, if I call any/all of these extensions in the same way, they work?

public static void AppendLine(this RichTextBox richTextBox)
{
    richTextBox.AppendText(Environment.NewLine);
}

public static void AppendLine(this RichTextBox richTextBox, string text)
{
    richTextBox.AppendText(text + Environment.NewLine);
}

public static void AppendLine(this RichTextBox richTextBox, string text, params object[] args)
{
    richTextBox.AppendLine(string.Format(text, args));
}

我想念什么?还是有另一种方法可以将彩色文本写入实时出价?

What am I missing? or is there another way to write coloured text to a RTB?

推荐答案

在您的 UpdateResultsLine 方法中需要一个 else 语句.当需要 Invoke 时,您正在使用委托(调用)执行 UpdateResultsLine 方法,但是随后您再次调用而无需使用 Invoke

You need an else statement in your the UpdateResultsLine method. When Invoke is required, you are executing the UpdateResultsLine method using the delegate (invoking), but then you call again without using Invoke

此外,为什么还要使用 BeginInvoke (异步)并使用 Invoke (同步)?您确定没有同步问题吗?使用Invoke并添加else语句可以解决您的问题:

Also, why do you use BeginInvoke (async) and use Invoke (sync)? Are you sure you have no sync problems? Using Invoke and adding an else statement could solve your problems:

private void UpdateResultsLine(string line, List<char> foundChars)
{
    if (txtResults.InvokeRequired)
    {
        txtResults.Invoke(
            new UpdateResultsLineDelegate(UpdateResultsLine),
            line,
            foundChars);
    }
    else
    {
        txtResults.AppendLine(
            line,
            foundChars,
            _fileType.ProcessColumns);
    }
}

这篇关于如何使用BeginInvoke从BackgroundWorker更新RichTextBox的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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