【问题标题】:How To Load UI Independent Of Data如何加载独立于数据的 UI
【发布时间】:2011-07-05 05:42:52
【问题描述】:

我正在使用 c# 和 webserver 中的数据库创建一个应用程序。从 webserver 访问数据时,速度很慢,并且在加载数据之前,表单也会挂起。有没有办法先加载表单和以后有数据吗?

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    解决这个问题的常用方法是使用BackgroundWorker 类。

    public void InitBackgroundWorker()
    {
        backgroundWorker.DoWork += YourLongRunningMethod;
        backgroundWorker.RunWorkerCompleted += UpdateTheWholeUi;
    
        backgroundWorker.WorkerSupportsCancellation = true; // optional
    
        // these are also optional
        backgroundWorker.WorkerReportsProgress = true;
        backgroundWorker.ProgressChanged += UpdateProgressBar;
    }
    
    // This could be in a button click, or simply on form load
    if (!backgroundWorker.IsBusy)
    {
        backgroundWorker.RunWorkerAsync(); // Start doing work on background thread
    }
    
    // ...
    
    private void YourLongRunningMethod(object sender, DoWorkEventArgs e)
    {
        var worker = sender as BackgroundWorker;
    
        if(worker != null)
        {
            // Do work here...
            // possibly in a loop (easier to do checks below if you do)
    
            // Optionally check (while doing work):
            if (worker.CancellationPending == true)
            {
                e.Cancel = true;
                break; // If you were in a loop, you could break out of it here...
            }
            else
            {
                // Optionally update
                worker.ReportProgress(somePercentageAsInt);
            }
    
            e.Result = resultFromCalculations; // Supports any object type...
        }
    }
    
    private void UpdateProgressBar(object sender, ProgressChangedEventArgs e)
    {
        int percent = e.ProgressPercentage;
        // Todo: Update UI
    }
    
    private void UpdateTheWholeUi(object sender, RunWorkerCompletedEventArgs e)
    {
        if (e.Cancelled)
        {
            // Todo: Update UI
        }
        else if (e.Error != null)
        {
            string errorMessage = e.Error.Message;
            // Todo: Update UI
        }
        else
        {
            object result = e.Result;
            // Todo: Cast the result to the correct object type,
            //       and update the UI
        }
    }
    

    【讨论】:

    【解决方案2】:

    听说过多线程吗?有关示例,请参见 thisthis

    【讨论】:

      【解决方案3】:

      如果多线程对您来说很难,您可以先加载部分数据,然后在表单上放置一些按钮,让用户获取其他部分数据。这通常称为按需加载,实现时称为分页。假设您有 10000 条信息记录。您可以加载前 100 条记录,然后让用户仅在需要时加载后 100 条记录。如果您在服务器上进行一些冗长的操作并且问题不在于按需加载,那么唯一的方法就是使用线程:)

      【讨论】:

        【解决方案4】:

        您可以在其他thread 中获取数据,而不是在UI thread 中。这样你的 UI 就不会卡住。看看这篇解释threading的帖子。 请记住,您不能从创建控件的线程以外的线程更新控件。要解决此问题,请查看post

        【讨论】:

          【解决方案5】:

          您使用什么样的数据?

          您可以使用 BackgroundWorker,或者在某些情况下可以使用异步方法(例如,如果您调用 webservivce)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2018-11-17
            • 2010-12-21
            • 1970-01-01
            • 1970-01-01
            • 2020-11-11
            • 1970-01-01
            • 1970-01-01
            • 2018-04-07
            相关资源
            最近更新 更多