Вывод большого количества данных
Есть обычный Windows Form's и огромные объемы данных,которые надо на него вывести,желательно с выделением некоторых слов другим текстом + функция автоскролла.
Вопрос в том,как лучше и выгоднее это сделать.Пробовал через RichTextBox,чуть не заснул, пока он это делал.
Может кто сталкивался? Писать класс что-то не хочется...
{
double[] a = new double[4000];
for (int i = 0; i < 4000; i++)
{
a[i] = 2.66;
}
for (int i = 0; i < 3990; i++)
{
if ((a[i]>2.11) && (a[i]<4.11))
{
richTextBox1.Text += a[i]+" ";
richTextBox1.Text += a[i+1] + " ";
richTextBox1.Text += a[i+2] + " ";
richTextBox1.Text += a[i+3] + " ";
richTextBox1.Text += a[i+4] + Environment.NewLine;
}
}
}
Ответы (2 шт):
Для объединения большого количества строк следует использовать класс StringBuilder. О нём обязательно рассказывают в каждом учебнике или курсе по C#.
Но конкатенация строк - это мелочь в вашем коде по сравнению с тем, что много тысяч раз обновляется свойство GUI-контрола - именно это тормозит: richTextBox1.Text = ... При каждом обновлении свойства графический контрол должен перерисоваться, проскроллиться и т. п. Поэтому следует сделать это один раз, присвоив ему сразу всё.
const int count = 4000;
double[] a = new double[count];
for (int i = 0; i < count; i++)
{
a[i] = 2.66;
}
var builder = new StringBuilder();
for (int i = 0; i < count - 5; i += 5)
{
if ((a[i] > 2.11) && (a[i] < 4.11))
{
builder
.Append(a[i]).Append(' ')
.Append(a[i + 1]).Append(' ')
.Append(a[i + 2]).Append(' ')
.Append(a[i + 3]).Append(' ')
.Append(a[i + 4]).AppendLine();
}
}
richTextBox1.Text = builder.ToString();
Для такого кол-ва данных я бы использовал ListView с включённым виртуальным режимом. Особенно, если данные будут обновляться.
using System;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Test
{
public partial class Form1 : Form
{
double[] a = new double[10000];
public Form1()
{
InitializeComponent();
listView1.RetrieveVirtualItem += (sender, item) =>
item.Item = new ListViewItem(a[item.ItemIndex].ToString("F3"), 0);
}
async private void button2_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
Parallel.For(0, a.Length, i =>
{
a[i] = RandomGen.Next();
});
});
}
private void button1_Click(object sender, EventArgs e)
{
listView1.VirtualListSize = a.Length;
}
}
public static class RandomGen
{
private static Random global = new Random();
[ThreadStatic]
private static Random local;
public static int Next()
{
Random instance = local;
if (instance == null)
{
int seed;
lock (global) seed = global.Next();
local = instance = new Random(seed);
}
return instance.Next(1,4);
}
}
}
Класс RandomGen и обработчик события button2_Click приведены лишь для генерации самих данных. Жертвуем ресурсами ради скорости.
В button1_Click указываем, что listView1 необходимо обновить свою коллекцию элементов в размере a.Length, затем необходимо обработать событие RetrieveVirtualItem, и собственно всё. Моментально заполняем данными наш listView1. (Ну, у меня на ПК это происходит моментально)