Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在richtextbox中查找所有换行符_C#_.net_Winforms_Richtextbox - Fatal编程技术网

C# 在richtextbox中查找所有换行符

C# 在richtextbox中查找所有换行符,c#,.net,winforms,richtextbox,C#,.net,Winforms,Richtextbox,我正在处理一个自定义texteditor控件,遇到了这个问题 我需要一个函数来获取文本中每个换行符“\n”的字符索引。 我有两种方法来实现这一点: private List<int> GetNewLineLocations() { var list = new List<int>(); int ix = 0; foreach (var c in this.Text) { if

我正在处理一个自定义texteditor控件,遇到了这个问题

我需要一个函数来获取文本中每个换行符“\n”的字符索引。 我有两种方法来实现这一点:

private List<int> GetNewLineLocations()
    {
        var list = new List<int>();
        int ix = 0;
        foreach (var c in this.Text)
        {
            if (c == '\n') list.Add(ix);
            ix++;
        }
        Debug.WriteLine(ix);
        return list;
    }
private List GetNewLineLocations()
{
var list=新列表();
int ix=0;
foreach(此.Text中的var c)
{
如果(c=='\n')列表。添加(ix);
ix++;
}
调试写线(ix);
退货清单;
}
以及:

private List GetNewLineLocations()
{
var list=新列表();
int ix=-1;
for(int i=0;i
第一种解决方案确实有效,但会减慢在richtextbox中输入的文本的速度。richtextbox大约有40000个字符,但可以分散在许多行中,如20000个

第二个似乎更快,因为它循环次数更少,做的也差不多,但在1000行时,无论包含多少文本,速度都会显著减慢

代码当然需要快速运行,而不是占用大量资源,这就是为什么我认为第二种解决方案会更好的原因

我的问题是:

  • 哪种解决方案更好?为什么

  • 为什么第二个解决方案会如此缓慢

  • 还有更好的解决办法吗

  • 当使用字符串时,非常好用。但他们不是最快的。如果您需要更快的处理,您应该在较低的级别上并行处理。确保使用long-as-index,因为int最多只允许处理2^31个字符,而long最多允许处理2^63个字符

    我同意 世卫组织在评论中说:


    问题在于,在富文本框中提取文本的标准函数实际上是一个必须过滤掉RTF标记的处理函数。获取文本的实际功能是瓶颈,而不是它后面的功能

    因此,您的数据应该保存在代码中的某个位置,而不是用户界面中。在处理长文本时,迟早会遇到麻烦,比如滚动时出现口吃或进一步出现瓶颈。我只表示可以在控件中显示的行。因此,您应该过度考虑应用程序设计。将数据存储在后端将允许您直接访问数据,而无需依赖文本框方法或其他用户界面内容

    下面是一个如何使用.net framework的简化处理数据的示例:

        using System;
        using System.Collections.Generic;
        using System.Text;
        using System.Threading.Tasks;
    
        namespace ConsoleApp1
        {
            internal class Program
            {
                public static byte[] _globalDataStore { get; set; }
                private static void Main(string[] args)
                {
                    DoStuff();
                    ShowDone();
                }
    
                private static void ShowDone()
                {
                    Console.WriteLine("done...");
                    Console.ReadKey();
                }
    
                private static void DoStuff()
                {
                    var tempData = GetData();
                    StoreData(ref tempData);
                    tempData = null; //free some ram
                    var dataIdentifier = (byte)'\n';
                    GetAndPromptDataPositions(_globalDataStore, dataIdentifier);
                }
    
                private static void GetAndPromptDataPositions<T>(T[] data, T dataIdentifier)
                {
                    var dataPositionList = GetDataPositions<T>(data, dataIdentifier);
                    PromptDataPostions(dataPositionList);
                }
    
                private static void PromptDataPostions(IEnumerable<long> positionList)
                {
                    foreach (var position in positionList)
                    {
                        Console.WriteLine($"Position '{position}'");
                    }
                }
                private static string GetData()
                {
                    return "aasdlj\naksdlkajsdlkasldj\nasld\njkalskdjasldjlasd";
                }
    
                private static void StoreData(ref string tempData)
                {
                    _globalDataStore = Encoding.ASCII.GetBytes(tempData);
                }
    
                private static List<long> GetDataPositions<T>(T[] data, T dataToFind)
                {
                    lock (data) //prevent data from being changed while processing, important when have other threaded could write data 
                    {
                        var postitonList = new List<long>();
                        Parallel.For(0, data.LongLength, (position) =>
                        {
                            if (data[position].Equals(dataToFind))
                            {
                                lock (postitonList) //lock list because of multithreaded access to prevent data corruption
                                {
                                    postitonList.Add(position);
                                }
                            }
                        });
                        return postitonList;
                    }
                }
            }
        }
    
    使用系统;
    使用System.Collections.Generic;
    使用系统文本;
    使用System.Threading.Tasks;
    名称空间控制台EAPP1
    {
    内部课程计划
    {
    公共静态字节[]\u全局数据存储{get;set;}
    私有静态void Main(字符串[]args)
    {
    DoStuff();
    ShowDone();
    }
    私有静态void ShowDone()
    {
    控制台。WriteLine(“完成…”);
    Console.ReadKey();
    }
    私有静态void DoStuff()
    {
    var tempData=GetData();
    StoreData(参考tempData);
    tempData=null;//释放一些ram
    变量数据标识符=(字节)'\n';
    GetAndPromptDataPositions(_globalDataStore,dataIdentifier);
    }
    私有静态void GetAndPromptDataPositions(T[]数据,T dataIdentifier)
    {
    var dataPositionList=GetDataPositions(数据,数据标识符);
    PromptDataPositions(数据位置列表);
    }
    私有静态无效PromptDataPostions(IEnumerable positionList)
    {
    foreach(位置列表中的var位置)
    {
    WriteLine($“Position'{Position}'”);
    }
    }
    私有静态字符串GetData()
    {
    返回“aasdlj\naksdlkajsdlkasldj\nasld\njkalskdjasldd”;
    }
    私有静态void存储数据(参考字符串tempData)
    {
    _globalDataStore=Encoding.ASCII.GetBytes(tempData);
    }
    私有静态列表GetDataPositions(T[]数据,T dataToFind)
    {
    lock(data)//防止数据在处理时被更改,当其他线程可以写入数据时,这一点很重要
    {
    var positonlist=新列表();
    平行。对于(0,data.LongLength,(位置)=>
    {
    if(数据[position].Equals(dataToFind))
    {
    lock(positonlist)//由于多线程访问而锁定列表,以防止数据损坏
    {
    职位列表。添加(职位);
    }
    }
    });
    返回帖子列表;
    }
    }
    }
    }
    
    我尝试了您的示例和Felix的,以及我自己的解决方案,使用了一个富文本框和40k行。结果是这是最快的,我看不到任何减速。你能试着把线数组作为参数传递给我们并告诉我们结果吗

    public static List<int> GetNewLineLocations(this string[] lines)
            {
                var list = new List<int>();
                int ix = -1;
    
                for (int i = 0; i < lines.Length; i++)
                {
                    ix += lines[i].Length+1;
                    list.Add(ix);
                }
    
                return list;
            }
    
    公共静态列表GetNewLineLocations(此字符串[]行)
    {
    var list=新列表();
    int ix=-1;
    对于(int i=0;i
    不幸的是,我无法实现这一点。至少没有更好更快的方法,您不需要解析
    \n
    字符和存储索引。您已经有了行和
    文本框的集合
    
    public static List<int> GetNewLineLocations(this string[] lines)
            {
                var list = new List<int>();
                int ix = -1;
    
                for (int i = 0; i < lines.Length; i++)
                {
                    ix += lines[i].Length+1;
                    list.Add(ix);
                }
    
                return list;
            }