我知道我在这里度过了一个沉重的深度,这实际上很容易做到-我四处搜寻并阅读了几篇文章,但我仍然在努力挣扎,因此任何对有用资源的反馈或指示都会不胜感激!
无论如何,我都有一个名为PopulateDatagridViews
的类,我在其中具有各种功能,其中一个名为ExecuteSqlStatement
,此功能非常简单,它初始化SQL连接并返回填充有SQL查询结果的DataTable
。在同一个类中,我还具有使用字符串生成器构建SQL语句的各种函数。 (不理想,我知道。)
我在GUI线程中创建了一个PopulateDatagridViews
对象,并使用它与返回的DataTables
一起设置各种datagrid View 。例如:
dataGridViewVar.DataSource = populateDgv.GetCustomers();
自然地,我遇到的一个问题是,要从数据库读取的数据越多,U.I的响应时间就越长。我想将通过
PopulateDatagridViews
检索数据的过程转移到单独的线程或BackgroundWorker
,以防止在处理此过程时主GUI线程锁定。我意识到我可以创建一个
BackgroundWorker
来做到这一点,并在DoWork
处理程序中放置对PopulateDatagridViews
中的适当函数的调用。我认为可以为
BackgroundWorker
类中的每个单独函数创建一个PopulateDatagridViews
,但是肯定有更有效的方法吗?我非常感激正确方向上的一点,因为它使我绕过弯道!附加信息:我使用.Net框架的4.0版。
最佳答案
我强烈建议您使用TPL(任务并行库)http://msdn.microsoft.com/en-us/library/dd537609.aspx
在您的情况下,您将创建第一个任务以提取一些数据,然后在完成第一个任务以更新UI之后启动第二个任务。
我将尝试查找针对类似问题编写的代码。
编辑:添加代码
Task<return_type> t1 = new Task<return_type>(() =>
{
//do something to take some result
return some_result; //return it
});
t1.Start();
Task t2 = t1.ContinueWith((some_arg_that_represent_previous_task_obj) =>{//ContinueWith guarantees that t2 is started AFTER t1 is executed!
//Update your GUI here
//if you need result from previos task: some_arg_that_represent_previous_task_obj.Result //Your dataset or whatever
}, TaskScheduler.FromCurrentSynchronizationContext()); //VERY important - you must update gui from same thread that created it! (you will have cross thread exeption if you dont add TaskScheduler.FromCurrentSynchronizationContext()
希望能帮助到你。