【发布时间】:2010-12-18 18:05:49
【问题描述】:
很多时候,我们在表单加载时使用来自 DB 的数据填充 UI,这就是表单冻结几秒钟的原因。所以我只想知道如何异步加载数据并在表单加载中填充 UI,因此我的表单不会冻结并且也会响应,但我不想使用后台工作类。请帮助我提供可以解决我的问题的示例代码。
谢谢
【问题讨论】:
-
为什么不想使用后台工作者?
标签: c#
很多时候,我们在表单加载时使用来自 DB 的数据填充 UI,这就是表单冻结几秒钟的原因。所以我只想知道如何异步加载数据并在表单加载中填充 UI,因此我的表单不会冻结并且也会响应,但我不想使用后台工作类。请帮助我提供可以解决我的问题的示例代码。
谢谢
【问题讨论】:
标签: c#
这是一个注释很好的示例代码:
// 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.
}
【讨论】:
Command.BeginExecuteReader()
可以满足您的阅读需求。
这里是 Sample Code 这个方法。
您可以在等待响应时致电Application.DoEvents() 以保持窗口响应。
【讨论】:
@Downvoter,请礼貌地让大家知道为什么你觉得有必要否决这个。
它仍然使用后台工作者。老实说,除了线程化您的应用程序以执行查询并绑定返回的结果之外,我想不出其他解决方案。如果你决定使用线程,那么我建议你看看这篇关于异步执行线程池的文章:http://www.yoda.arachsys.com/csharp/threads/threadpool.shtml
【讨论】:
您最好的做法是使用另一个线程。您可以通过调用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
}
}
}
}
【讨论】: