【发布时间】:2011-07-05 05:42:52
【问题描述】:
我正在使用 c# 和 webserver 中的数据库创建一个应用程序。从 webserver 访问数据时,速度很慢,并且在加载数据之前,表单也会挂起。有没有办法先加载表单和以后有数据吗?
【问题讨论】:
我正在使用 c# 和 webserver 中的数据库创建一个应用程序。从 webserver 访问数据时,速度很慢,并且在加载数据之前,表单也会挂起。有没有办法先加载表单和以后有数据吗?
【问题讨论】:
解决这个问题的常用方法是使用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
}
}
【讨论】:
Task class
如果多线程对您来说很难,您可以先加载部分数据,然后在表单上放置一些按钮,让用户获取其他部分数据。这通常称为按需加载,实现时称为分页。假设您有 10000 条信息记录。您可以加载前 100 条记录,然后让用户仅在需要时加载后 100 条记录。如果您在服务器上进行一些冗长的操作并且问题不在于按需加载,那么唯一的方法就是使用线程:)
【讨论】:
您使用什么样的数据?
您可以使用 BackgroundWorker,或者在某些情况下可以使用异步方法(例如,如果您调用 webservivce)
【讨论】: