【问题标题】:WPF C# Application Took too long to get data from SQL ServerWPF C# 应用程序从 SQL Server 获取数据的时间太长
【发布时间】:2019-04-21 02:11:03
【问题描述】:

我有一个连接到 SQL Server 的 WPF 应用程序;虽然我将最多 10 条记录加载到我的 DataGrid 中,但我的应用程序工作正常并且响应速度太快,但是当我加载所有行(几乎是 1000 行)时,我的应用程序需要大约 15 秒来加载并冻结整个 UI。

但是当我在 SQL Server 中执行相同的查询时,加载这 1000 行只需要大约 00:00:00.490 秒,这太快了。为了避免 UI 冻结和快速执行查询,我已经做了如下操作。我做错了什么?由于我是 C# 世界的新手,请使用代码 sn-ps 进行指导。

// 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(); 

但不幸的是,我的 UI 显示消息“无响应”。下面是函数定义:

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>

我希望我的 UI 能够快速响应并快速加载数据。我现在正在本地主机上工作。

【问题讨论】:

  • 您需要所有列吗?如果不需要,则仅在 select 子句中提及这些列。也分配没有线程的数据网格
  • @S.Akbari 因为我也在使用 Dispatcher 和 New Thread 我做错了什么?你能多指导一点吗?我已经浏览了您提供的链接。
  • @SatishPai 是的!我需要所有列的全部数据。
  • 是的,您正在生成一个新线程,然后再次在 UI 线程上执行实际的数据库访问 (Application.Current.Dispatcher)

标签: c# sql-server wpf user-interface


【解决方案1】:

启动新的后台线程从表中查询数据,如下所示:

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 的回复,但不幸的是,这个解决方案也无法正常工作我的 UI 仍然冻结我已经确定了这行 dg.ItemsSource = dt.DefaultView 中的问题,如果我评论它一切正常所以原因是在将数据从数据表加载到 DataGrid 时冻结了我的 UI,我不知道如何处理它。
  • @asim.ali314 请提供单行数据的样本。我觉得这个答案应该可以解决问题。
  • 我在一个表中有 25 列,每个表的类型为 VARCHAR(250) 到 VARCHAR(1000),因为数据包含很多细节。可能这可以帮助你吗?此外,我的数据仅包含文本。
【解决方案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);
          }
    }));                            
}

希望对你有帮助!

【讨论】:

  • 不幸的是它对我不起作用!问题仍然存在,我的 UI 冻结并停止响应,直到数据加载到 DataGrid 之后,一切都像正常一样进入平滑状态。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-31
  • 2017-12-20
  • 1970-01-01
  • 2014-03-03
  • 2017-08-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多