如何加载独立于数据的UI

时间:2011-07-05 05:42:52

标签: c# winforms

我正在使用web服务器中的c#和数据库创建一个应用程序。从Web服务器访问数据时,它非常慢,并且表单也被挂起,直到数据被加载。有一种方法可以先加载表单数据库以后?

5 个答案:

答案 0 :(得分:3)

解决此问题的常用方法是使用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
    }
}

答案 1 :(得分:2)

听说多线程?有关示例,请参阅thisthis

答案 2 :(得分:2)

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

您使用的是哪种数据?

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