Приложение WPF C# Слишком долго для получения данных от SQL Server

У меня есть приложение WPF, подключенное к SQL Server; пока я загружаю в свой DataGrid до 10 записей, мое приложение работает нормально, а ответ слишком быстрый, но когда я загружаю все строки (а это почти 1000), моему приложению потребовалось около 15 секунд для загрузки и зависания всего пользовательского интерфейса.

Но когда я выполняю тот же запрос в SQL Server, загрузка этих 1000 строк занимает всего около 00: 00: 00,490 секунд, что слишком быстро. Я уже сделал следующее, чтобы избежать зависания пользовательского интерфейса и быстрого выполнения запросов. Что я делаю не так? Пожалуйста, помогите с фрагментами кода, так как я новичок в мире C#.

// Calling function to load data into DataGrid in a new thread,
// to make UI responsive.
String qry = "select * from institutes_tbl"
DataGrid dg = MainDataGrid;
Thread thread = new Thread(() => FunDataGrid_DataView(dg, qry));
thread.IsBackground = true;
thread.Start(); 

Но, к сожалению, в моем интерфейсе отображается сообщение «Не отвечает». Ниже приведено определение функции:

public void FunDataGrid_DataView(DataGrid dg, string qry)
{
    Application.Current.Dispatcher.BeginInvoke
    (
        DispatcherPriority.Background,
        new Action(() =>
        {                       
            try
            {
                con = new SqlConnection(con_string);
                cmd = new SqlCommand(qry, con);
                cmd.CommandTimeout = 12 * 3600;
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                DataTable dt = new DataTable();
                da.Fill(dt);
                dg.ItemsSource = dt.DefaultView;
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error!",
                    MessageBoxButton.OK, MessageBoxImage.Warning);
            }                                                                      
        }
    ));                            
}

Вот мой XAML:

<DataGrid x:Name = "DataGrid_View"
          MouseLeftButtonUp = "DataGrid_View_MouseLeftButtonUp"
          ItemsSource = "{Binding DATA_TBL}"
          LoadingRow = "DataGrid_View_LoadingRow" Grid.Row = "2"
          Grid.Column = "0" ScrollViewer.CanContentScroll = "False"
          AutoGenerateColumns = "False" CanUserAddRows = "False"
          Background = "#7F179DB2" CellStyle = "{StaticResource CellStyle}">
    <DataGrid.Columns>
        <DataGridTextColumn Header = "Name"
                            Binding = "{Binding NAME}" Width = "5*"/>
        <DataGridTextColumn Header = "Father Name"
                            Binding = "{Binding F_NAME}" Width = "5*"/>
        <DataGridTextColumn Header = "CNIC"
                            Binding = "{Binding CNIC}" Width = "5*"/>
    </DataGrid.Columns>
</DataGrid>

Я хочу, чтобы мой пользовательский интерфейс был отзывчивым, а данные загружались быстро. Я сейчас работаю на локальном хосте.

stackoverflow.com/a/30680600/2946329
Salah Akbari 18.11.2018 16:19

вам нужны все столбцы? Если нет, то укажите только эти столбцы в предложении select. Также назначьте сетку данных без потоковой передачи

Sats 18.11.2018 16:23

@ S.Akbari Поскольку я также использую Диспетчер и Новую тему Что я делаю не так? Не могли бы вы рассказать немного больше? Я перешел по указанной вами ссылке.

asim.ali314 18.11.2018 16:24

@SatishPai Да! Мне нужны целые данные по всем столбцам.

asim.ali314 18.11.2018 16:25

Да, вы создаете новый поток, но затем снова выполняете фактический доступ к базе данных в потоке пользовательского интерфейса (Application.Current.Dispatcher)

Klaus Gütter 18.11.2018 16:27

у вас есть сетка данных внутри средства просмотра прокрутки в xaml?

Sats 18.11.2018 16:27

@ KlausGütter, но если я не использую диспетчер, он говорит: «Вызывающий поток не может получить доступ к этому объекту, потому что он принадлежит другому потоку» Что мне делать для этого?

asim.ali314 18.11.2018 16:30

@SatishPai Нет, в моей сетке данных нет средства просмотра прокрутки.

asim.ali314 18.11.2018 16:42
Application.Current ... хм ... это основной поток пользовательского интерфейса, в который вы отправляете. Вероятно, объясняет, почему UI зависает: поток, который управляет ответами UI на действия пользователя, занят выполнением работы SQL. По какой-то причине? Обычно вы хотите вызвать основной поток пользовательского интерфейса только для принудительного обновления контекста и, используя концепции MVVM, это означает, что вы выполняете то, что называется вызовом INPC (INotifyPropertyChanged). Используйте этот поток для обновления класса viewmodel, который реализует INPC, и вы должны вернуться на «счастливый путь» WPF.
code4life 18.11.2018 19:06

Несвязанные советы: SqlConnection SqlCommand и SqlDataAdapter - все IDisposable, поэтому каждый должен быть в блоке using.

Richardissimo 18.11.2018 21:30

@ code4life Я не реализовал MVVM, но это простое приложение

asim.ali314 19.11.2018 08:32

Убедитесь, что вы каким-то образом не отключили виртуализацию пользовательского интерфейса. Пожалуйста, опубликуйте свой XAML для получения дополнительной помощи.

mm8 19.11.2018 14:22

@ mm8 Я обновил свой вопрос и разместил свой XAML, пожалуйста, посмотрите.

asim.ali314 19.11.2018 17:35

Попробуйте указать фактическую высоту Datagrid. Проблема здесь, похоже, в том, что вы даете своей сетке данных достаточно места для рендеринга каждого элемента без виртуализации. Поэтому попробуйте поместить его, например, в сетку с определением строки размером 400 и проверьте, загружается ли пользовательский интерфейс быстрее.

Brezelmann 15.09.2021 14:29
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
14
144
2

Ответы 2

Попробуй это:

public void FunDataGrid_DataView(DataGrid dg, string qry)
{
    con = new SqlConnection(con_string);
    cmd = new SqlCommand(qry, con);
    cmd.CommandTimeout = 12 * 3600;
    SqlDataAdapter da = new SqlDataAdapter(cmd);
    DataTable dt = new DataTable();
    da.Fill(dt);
    Application.Current.Dispatcher.BeginInvoke(
      DispatcherPriority.Background,
      new Action(() =>
      {                       
          try
          {
              dg.ItemsSource = dt.DefaultView;
          }
          catch (Exception ex)
          {
              MessageBox.Show(ex.Message, "Error!",
                  MessageBoxButton.OK, MessageBoxImage.Warning);
          }
    }));                            
}

Надеюсь, поможет!

К сожалению, у меня это не сработало! Проблема все еще существует, мой пользовательский интерфейс зависает и перестает отвечать, пока данные не будут загружены в DataGrid. После этого все перешло в нормальное состояние.

asim.ali314 18.11.2018 16:45

Запустите новый фоновый поток для запроса данных из таблицы, как показано ниже:

Task.Factory.StartNew(() =>
{
    try
    {
        con = new SqlConnection(con_string);
        cmd = new SqlCommand(qry, con);
        cmd.CommandTimeout = 12 * 3600;
        SqlDataAdapter da = new SqlDataAdapter(cmd);
        DataTable dt = new DataTable();
        da.Fill(dt);
        Application.Current.Dispatcher.BeginInvoke
        (
            DispatcherPriority.Background,
            new Action(() => dg.ItemsSource = dt.DefaultView)
        );
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error!", MessageBoxButton.OK,
            MessageBoxImage.Warning);
    }
});

Спасибо за ответ @RajN, но, к сожалению, это решение также не работает, мой пользовательский интерфейс все еще зависает. Я обнаружил проблему, которая находится в этой строке dg.ItemsSource = dt.DefaultView, если я прокомментирую, все работает нормально, поэтому причина в загрузке данных из таблица данных в DataGrid замораживает мой пользовательский интерфейс, я не знаю, как с этим справиться.

asim.ali314 19.11.2018 08:30

@ asim.ali314 Предоставьте образец одной строки данных. Я считаю, что этот ответ должен помочь.

Michael Puckett II 19.11.2018 17:38

У меня 25 столбцов в таблице, каждая таблица имеет тип от VARCHAR (250) до VARCHAR (1000), поскольку данные содержат много деталей. Может быть, это поможет? Более того, мои данные содержат только текст.

asim.ali314 20.11.2018 15:45

Другие вопросы по теме