Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Базы данных под .NET > Ускорение вывода данных в datagridview


Автор: XavierElf 25.4.2007, 16:15
Не знаю как решить проблему: имеется datagridview, который заполняется из dataset, проблема в том, что когда в datagridview заполняются тысяч десять рядов, при сортировке он начинает надолго задумываться... плюс к тому, для каждого ряда задаётся свой forecolor, который при сортировке сбрасывается... как можно ускорить сортировку и сделать так, чтобы после неё forecolor сохранялся?

Автор: Exception 25.4.2007, 16:59
Боюсь, что с таким количеством строк он всегда будет долго грузиться.

Автор: 6atoh 25.4.2007, 19:58
При таких больших обьемах данных советую всегда использовать Repeater. Ну и соответственно сортировку приходится ручками...

Автор: Exception 25.4.2007, 21:14
Дык мы (если я правильно понял) про контрол Windows Forms.

Автор: 6atoh 25.4.2007, 22:41
Ужос.....совсем заэспэнэтился smile 

Автор: XavierElf 26.4.2007, 09:35
Мда... А нельзя данные загонять в промежуточный буфер для последующего вывода, а то у меня есть программа (правда исходников нет), которая также написана с помощью WinForms и в ней загрузка данных в гриду и сортировка происходят практически мгновенно, а строк загружается в гриду порядка 40000... Как такое возможно?  smile 

Автор: LuMee 26.4.2007, 10:06
Данные всегда будут в промежуточном буфере, типа того же DataTable. Вообще, тут неплохо бы посмотреть код, возможно, тормозит как раз процесс заполнения DataTable'а, или кто у вас там гридвью данными кормит...
Как вариант, можно еще призадуматься - а зачем пользователю 10 тыс. строк на экране сразу? Возможно, следует наложить на данные какие-то доп. фильтры, или еще чего в этом роде?

Автор: XavierElf 26.4.2007, 10:57
В общем вот код чтения данных:
Код

                #region read data
                string textString;
                string[] splittextString;
                object[] newtextRow;
                StreamReader textSR = new StreamReader(TempDir + "\\text.txt");
                textString = textSR.ReadLine();
                textString = textSR.ReadLine();
                int i = 0;
                while (textString != null)
                {
                    splittextString = textString.Split(new Char[] { '\t' });
                    newtextRow = new object[splittextString.Length - 3];
                    newtextRow[0] = splittextString[0];
                    newtextRow[1] = splittextString[1];
                    newtextRow[2] = splittextString[2];
                    newtextRow[3] = splittextString[5] + splittextString[4] + splittextString[3];
                    textDGV.Rows.Add(newtextRow);
                    textDGV.Rows[i].DefaultCellStyle.ForeColor = Color.FromArgb(
                        int.Parse(splittextString[5], System.Globalization.NumberStyles.HexNumber), 
                        int.Parse(splittextString[4], System.Globalization.NumberStyles.HexNumber), 
                        int.Parse(splittextString[3], System.Globalization.NumberStyles.HexNumber));
                    textDGV.Rows[i].DefaultCellStyle.SelectionForeColor = Color.FromArgb(
                        int.Parse(splittextString[5], System.Globalization.NumberStyles.HexNumber), 
                        int.Parse(splittextString[4], System.Globalization.NumberStyles.HexNumber), 
                        int.Parse(splittextString[3], System.Globalization.NumberStyles.HexNumber));
                    textString = textSR.ReadLine();
                    i++;
                }
                textSR.Close();
                #endregion

Не знаю, как это лучше реализовать...

Автор: mr.DUDA 27.4.2007, 08:36
Цитата(LuMee @  26.4.2007,  10:06 Найти цитируемый пост)
Как вариант, можно еще призадуматься - а зачем пользователю 10 тыс. строк на экране сразу?

Согласен на 100%. Такой грид неудобно скроллировать и сложно найти то что требуется.

Автор: XavierElf 28.4.2007, 08:50
Хорошо, тогда как лучше разбить на страницы где-то по тысяче строк? И сделать сортировку не видимых строк а всех строк, которые имеются?

Автор: mr.DUDA 29.4.2007, 08:56
Запрос делать с указанием TOP COUNT, а для сортировки - ORDER BY.

Автор: XavierElf 2.5.2007, 09:12
Цитата(mr.DUDA @ 29.4.2007,  08:56)
Запрос делать с указанием TOP COUNT, а для сортировки - ORDER BY.

А если я данные беру не из базы а из файла? То есть у меня есть файл, определённой структуры. В нём разделители значений представлены табуляцией. Пробовал загружать из него сначала в датасет, потом из датасета в гриду, однако скорость была совсем уж страшной... Сделал напрямую вывод в гриду, однако всё равно не то...

Автор: LuMee 3.5.2007, 10:29
Думаю, с файлом тут быстро полюбому не получится. Ну разве что файл читать кусками: показать юзеру, скажем, 200 строк, потом по кнопке "Далее" - еще 200, ну в общем сделать что-то вроде постраничной разбивки.
Для пущего пафоса можно еще так извратиться: пусть первые 200 строк сразу заносятся в грид, а остальные тем временем в отдельном потоке засасываются в какой-нить List или DataTable, который затем задается в качестве DataSource гриду. Но тут уже надо будет хорошенько подумать, что да как.
Ну и наконец, может все-таки посмотреть в сторону какой-нибудь простенькой СУБД (типа SQLite или еще чего-нить такого встраиваемого)? С ней такие выкрутасы выкручивать будет попроще

Автор: XavierElf 3.5.2007, 11:36
Цитата(LuMee @ 3.5.2007,  10:29)
Думаю, с файлом тут быстро полюбому не получится. Ну разве что файл читать кусками: показать юзеру, скажем, 200 строк, потом по кнопке "Далее" - еще 200, ну в общем сделать что-то вроде постраничной разбивки.
Для пущего пафоса можно еще так извратиться: пусть первые 200 строк сразу заносятся в грид, а остальные тем временем в отдельном потоке засасываются в какой-нить List или DataTable, который затем задается в качестве DataSource гриду. Но тут уже надо будет хорошенько подумать, что да как.
Ну и наконец, может все-таки посмотреть в сторону какой-нибудь простенькой СУБД (типа SQLite или еще чего-нить такого встраиваемого)? С ней такие выкрутасы выкручивать будет попроще

С базой уж точно нет смысла возиться... Дело в том, что с файлом, с которым я работаю, нужно провести следующие выкрутасы:
1) Декодировать
2) Дизасемблировать
3) Загрузить в гриду
4) В гриде изменить нужные куски файла
5) Сохранить в файл
6) Ассемблировать
7) Закодировать

ЗЫ. Чтобы не возникало никаких подозрений - я работаю над программой, которая работает со строковой информацией одной игры... Грубо говоря - для удобства локализации и т.п.  smile 

Автор: mr.DUDA 5.5.2007, 18:47
XavierElf, может проще заюзать готовый провайдер для текстовых файлов (CSV например) который встроен в .NET Framework ? Тогда и нормальные SQL-запросы можно делать.

Автор: XavierElf 7.5.2007, 08:45
Цитата(mr.DUDA @  5.5.2007,  18:47 Найти цитируемый пост)
XavierElf, может проще заюзать готовый провайдер для текстовых файлов (CSV например) который встроен в .NET Framework ? Тогда и нормальные SQL-запросы можно делать.

А поподробнее про это можно? А то я с CSV раньше не сталкивался. Какие классы следует использовать для этого?

Автор: mr.DUDA 7.5.2007, 09:47
OleDbConnection, OleDbCommand для соединения и создания запроса; OleDbDataAdapter - для чтения и сохранения данных в датасет. Строку соединения для коннекшна можно посмотреть тут: www.connectionstrings.com

Автор: XavierElf 7.5.2007, 10:23
Я так понял, что разделитель колонок (delimiter) нужно указывать в реестре. А мне вообще не хочется использовать реестр. Есть ли возможность указывать разделитель в коде?

Автор: mr.DUDA 7.5.2007, 13:16
Можно подкинуть shema.ini рядом с файлом бд:
Цитата
Schema.ini

_
The schema information file tells the driver about the format of the text files. The file is always located in the same folder as the text files and must be named schema.ini.    
[customers.txt]
Format=TabDelimited
ColNameHeader=True
MaxScanRows=0
CharacterSet=ANSI

[orders.txt]
Format=Delimited(;)
ColNameHeader=True
MaxScanRows=0
CharacterSet=ANSI

[invoices.txt]
Format=FixedLength
ColNameHeader=False
Col1=FieldName1 Integer Width 15
Col2=FieldName2 Date Width 15
Col3=FieldName3 Char Width 40
Col4=FieldName4 Float Width 20
CharacterSet=ANSI

Автор: XavierElf 22.5.2007, 12:31
Так, я попробовал как ты написал, однако теперь проблема возникла с запросом... Как правильно строить запрос типа SELECT к нужному мне CSV файлу?
Пробовал так:
Код

                using (OleDbConnection connection = new OleDbConnection(
                    "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + L2TempDir + 
                    ";Extended Properties=\"text;HDR=Yes;FMT=Delimited\";"))
                {
                    OleDbCommand command = new OleDbCommand(
                        "SELECT * " +
                        "FROM mycsvfile", connection);
                    connection.Open();
                    OleDbDataReader reader = command.ExecuteReader();
                    while (reader.Read())
                    {
                        MessageBox.Show(reader[0].ToString());
                    }
                }

выдаёт ошибку синтаксиса в предложении FROM...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)