Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки. / 10 сообщений из 10, страница 1 из 1
31.05.2017, 04:43
    #39462776
AlexV1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки.
Добрый день!

Моя задача : Сделать быструю загрузку и отображение данных в DataGridView.
И не важно в выборке 100 записей или 1 млн! - программа в любом случае должна быстро отобразить данные.
Данные хранятся локально в БД SQLite (db-файл рядом с exe).

Предполагаемое решение : запросить TOP 100 записей (точнее LIMIT 0,99 в SQLite) видимые на экране, отобразить в гриде, а далее запустить фоновый поток, который будет догружать порциями остальные данные в грид, скажем, по 10 тыс записей.
Сразу 1 млн записей по времени загружаются в грид у меня за 10 сек.
При фоновой дозагрузке это время должно остаться примерно таким же (10 сек) или чуть больше, но важно, чтобы дозагрузка не мешала работе с программой (не блокировала интерфейс).

В целом мой код работает, но есть проблема.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
namespace Many
{
    public partial class MainForm : Form
    {
        SQLiteConnection cn;
        SQLiteCommand cmd;
        SQLiteDataAdapter da;

        // 2-й поток для фоновой дозагрузки
        public static Thread Thread2;

        string gridSQL = ""; // Осн.запрос данных для грида

        public MainForm()
        {
            InitializeComponent();
        }

        // Подключаемся к БД SQLite
        public void DBConnect(string filedb)
        {
           cn = new SQLiteConnection(string.Format("Data Source={0};", filedb));
           cn.Open();
        }

        private void MainForm_Shown(object sender, EventArgs e)
        {
            string filedb = "many.db";
            string errSt = DBConnect(filedb);
            if (!RequeryGrid()) return;
        }

        // Перезапрос данных для грида из БД
        private void RequeryGrid()
        {
          if (Thread2!=null)
            if (Thread2.ThreadState == System.Threading.ThreadState.Background)
            {
                Thread2.Abort();
            }

          string SQL = "SELECT items.* FROM items ORDER BY id, title";
          gridSQL = SQL;

          cmd = new SQLiteCommand(gridSQL + " LIMIT 0,99", cn); // Первая быстрая порция 100 строк

          DataTable dt = new DataTable();

          // Use Adapter (адаптер пихает данные в DataTable), а DataTable потом присоединим к DataSource грида
          da = new SQLiteDataAdapter(cmd);
          da.SelectCommand = cmd;
          da.Fill(dt); // Загружаем только 100 записей и привязываем к гриду, остальные в другом потоке будем добавлять из адаптера в Source грида
          grid.DataSource = dt;
          // da.FillLoadOption(LoadOption.PreserveChanges);
          
          // Запускаем фоновую дозагрузку данных в грид

          Thread2 = new Thread(RequeryGridContinue);
          Thread2.IsBackground = true;                
          Thread2.Start();                
        }
        
        // Ф-я 2-го потока (дозагрузка в грид)
        void RequeryGridContinue()
        {            
            // В потоке2 будем подгружать из БД в грид по 10000 записей
            SQLiteCommand cmd = new SQLiteCommand(gridSQL + " LIMIT "+(grid.Rows.Count+1).ToString()+",9999", cn);
            SQLiteDataAdapter da = new SQLiteDataAdapter(cmd);
            da.Fill(((DataTable)grid.DataSource));
        }

        private void button1_Click(object sender, EventArgs e)
        {
            RequeryGridContinue();
        }
    }
}


Так вот проблема в том, что
если RequeryGridContinue запускает 2-й поток (Thread2), то da.Fill в нем работает очень медленно (примерно 100 записей в секунду), но
если эта же RequeryGridContinue была вызвана по тестовой кнопке на форме (из button1_Click), то 10000 записей добавятся в грид всего за 2-3 секунды , хотя и блокируя интерфейс.

Почему фоновая дозагрузка в потоке настолько медленно работает и как ее ускорить?
Также буду счастлив услышать критику данного решения вцелом и другие варианты решения задачи.
Заранее благодарю.
...
Рейтинг: 0 / 0
31.05.2017, 08:17
    #39462806
Barkan
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки.
AlexV1,

Я думаю в принципе не верно говорить о загрузке в DataGridView 1 млн. записей!
Кому они там нужны? Кто будет глазками их там просматривать?
Лучше подумайте над фильтрацией и / или обработкой данных, что бы ползателю выдавать уже результат обработки без визуальной "лапши".
...
Рейтинг: 0 / 0
31.05.2017, 09:40
    #39462854
mikron
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки.
AlexV1,

Создай вторую таблицу и загрузи туда данные полностью а потом поменяю DataSource.
О результатах сообщи.

ПС. Общая идея не понятна - кому и зачем так оно надо?
...
Рейтинг: 0 / 0
31.05.2017, 09:41
    #39462855
AlexV1
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки.
Barkan,

Да, вы правы. Визуально врядли юзеру нужно показывать 1 млн записей.
И все таки, чисто интересно сделать асинх.дозагрузку с DataGridView, пусть даже данное решение практического применения не будет иметь
...
Рейтинг: 0 / 0
31.05.2017, 10:48
    #39462928
Супер_Пав
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки.
Для работы с гуи рекомендую BackgroundWorker
...
Рейтинг: 0 / 0
31.05.2017, 10:50
    #39462930
Супер_Пав
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки.
AlexV1Barkan,

Да, вы правы. Визуально врядли юзеру нужно показывать 1 млн записей.
И все таки, чисто интересно сделать асинх.дозагрузку с DataGridView, пусть даже данное решение практического применения не будет иметь
сделайте дозагрузку на событие скрула, когда пользователь начинает прокрутку в гриде, догружайте по 100 записей. Зачем в памяти хранить 1кк записей. на 99.99% никто их смотреть не станет, а память засрете
...
Рейтинг: 0 / 0
31.05.2017, 10:52
    #39462931
Сон Веры Павловны
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки.
AlexV1Barkan,

Да, вы правы. Визуально врядли юзеру нужно показывать 1 млн записей.
И все таки, чисто интересно сделать асинх.дозагрузку с DataGridView, пусть даже данное решение практического применения не будет иметь
https://msdn.microsoft.com/en-us/library/15a31akc(v=vs.110).aspx
...
Рейтинг: 0 / 0
31.05.2017, 18:05
    #39463297
Sergey S
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки.
В грид биндить через биндингсоурс
Читать SQLDataReader-ом кучу строк и добавлять новые через БиндингСоурс
...
Рейтинг: 0 / 0
04.06.2017, 14:20
    #39465468
Arm79
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки.
Виртуальный режим работы, https://msdn.microsoft.com/ru-ru/library/15a31akc(v=vs.110).aspx
...
Рейтинг: 0 / 0
04.06.2017, 14:21
    #39465469
Arm79
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки.
Сон Веры Павловны,

сорри, не увидел ))))
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Асинхронная дозагрузка данных в DataGridView при большой выборке (1 млн записей). Потоки. / 10 сообщений из 10, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]