2

我知道我在这里有一个巨大的 derp 时刻,这实际上可能很容易做到 - 我已经搜索并阅读了一些文章,但我仍然有点挣扎,所以任何反馈或指向有用资源的指针都会不胜感激!

无论如何,我有一个名为的类PopulateDatagridViews,其中有各种函数,其中一个名为ExecuteSqlStatement,这个函数很简单,它初始化一个 SQL 连接并返回一个DataTable填充了 SQL 查询结果的函数。在同一个类中,我还有各种使用字符串构建器来构建 SQL 语句的函数。(不理想,我知道。)

PopulateDatagridViews我在我的 GUI 线程中创建了一个对象,并使用它来设置各种数据网格视图,并使用返回的DataTables. 例如:

dataGridViewVar.DataSource = populateDgv.GetCustomers();

我遇到的一个问题自然是从数据库中读取的数据越多,UI 无响应的时间就越长。我想将通过 检索数据的过程转移PopulateDatagridViews到一个单独的线程,或者BackgroundWorker防止主 GUI 线程在处理该线程时锁定。

我意识到我可以创建一个BackgroundWorker来执行此操作,并在DoWork处理程序中调用我的PopulateDatagridViews.

我想我可以为班级BackgroundWorker中的每个单独的函数创建一个PopulateDatagridViews,但肯定有更有效的方法来做到这一点吗?我非常感谢在正确的方向上指出这一点,因为它正在驱使我绕过弯道!

附加信息:我使用 .Net 框架的 4.0 版。

4

2 回答 2

1

那么在这种情况下,我建议阅读这篇msdn 文章以获得一些想法。之后你应该寻找一些教程,因为 msdn 不是学习东西的最佳来源。;o)

于 2012-12-10T15:49:39.873 回答
1

我强烈建议您使用 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()

希望能帮助到你。

于 2012-12-10T15:48:34.927 回答