【问题标题】:Loading data from DB asynchronously in win forms以win形式从数据库异步加载数据
【发布时间】:2010-12-18 18:05:49
【问题描述】:

很多时候,我们在表单加载时使用来自 DB 的数据填充 UI,这就是表单冻结几秒钟的原因。所以我只想知道如何异步加载数据并在表单加载中填充 UI,因此我的表单不会冻结并且也会响应,但我不想使用后台工作类。请帮助我提供可以解决我的问题的示例代码。

谢谢

【问题讨论】:

  • 为什么不想使用后台工作者?

标签: c#


【解决方案1】:

这是一个注释很好的示例代码:

示例:

// This method can be called on Form_Load, Button_Click, etc.
private void LoadData()
{
    // Start a thread to load data asynchronously.
    Thread loadDataThread = new Thread(LoadDataAsync);
    loadDataThread.Start();
}

// This method is called asynchronously
private void LoadDataAsync()
{
    DataSet ds = new DataSet();

    // ... get data from connection

    // Since this method is executed from another thread than the main thread (AKA UI thread),
    // Any logic that tried to manipulate UI from this thread, must go into BeginInvoke() call.
    // By using BeginInvoke() we state that this code needs to be executed on UI thread.

    // Check if this code is executed on some other thread than UI thread
    if (InvokeRequired) // In this example, this will return `true`.
    {
        BeginInvoke(new Action(() =>
        {
            PopulateUI(ds);
        }));
    }
}

private void PopulateUI(DataSet ds)
{
    // Populate UI Controls with data from DataSet ds.
}

【讨论】:

    【解决方案2】:
    Command.BeginExecuteReader()
    

    可以满足您的阅读需求。

    这里是 Sample Code 这个方法。

    您可以在等待响应时致电Application.DoEvents() 以保持窗口响应。

    【讨论】:

    • +1:好主意。另外@Downvoter,请礼貌地让大家知道为什么你觉得有必要否决这个。
    • 我知道它已经过时了,但这是拒绝投票的原因:blog.codinghorror.com/is-doevents-evil
    【解决方案3】:

    看看这篇文章。 http://aspadvice.com/blogs/azamsharp/archive/2007/04/05/Executing-a-Query-Asynchronously-in-.NET-2.0.aspx

    它仍然使用后台工作者。老实说,除了线程化您的应用程序以执行查询并绑定返回的结果之外,我想不出其他解决方案。如果你决定使用线程,那么我建议你看看这篇关于异步执行线程池的文章:http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml

    【讨论】:

      【解决方案4】:

      您最好的做法是使用另一个线程。您可以通过调用ThreadPool.QueueUserWorkItem 直接使用线程池中的一个。

          private void OnFormLoad()
          {
              ThreadPool.QueueUserWorkItem(() => GetSqlData());
          }
      
          private object GetSqlData()
          {
              using (var connection = new SqlCeConnection("ConnectionString"))
              {
                  using(var command = new SqlCeCommand())
                  {
                      command.Connection = connection;
                      command.CommandText = "SELECT * FROM tbl_hello";
                      command.ExecuteReader();
      
                      while (command.ExecuteReader().Read())
                      {
                          //Put data somewhere
                      }
                  }
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-01-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-07-19
        • 2020-11-22
        • 2020-11-24
        相关资源
        最近更新 更多