从后台线程填充DataGridView [英] Populating DataGridView from background thread

查看:83
本文介绍了从后台线程填充DataGridView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这个问题已经问了很多,我已经阅读了Stackoverflow上的所有帖子。

This question has been asked a lot, and I've read all the posts on Stackoverflow on it.

我想确认我的结论。

要填充的信息源非常快(即获取信息本身不需要花费很多处理时间),在我看来,处理需要花费时间实际上是将其输入到DataGridView中。

Where the source of information being populated is quite fast (ie it doesn't take much processing time to get the information itself), it seems to me that the processing that takes the time is actually feeding it into the DataGridView. However that has to be done on the UI thread as that's where the control is.

如果是这种情况,尝试在后台执行任何操作似乎没有什么好处。 ,必然的结果是,没有捆绑UI线程就没有有效的方法来填充DataGridView。

If that's the case there seems to be limited benefit to trying to do anything in the background, and that the corollary is that there's no effective way to populate a DataGridView without bunging up the UI thread. Is that right?

当然,必须有某种方法可以完全异步地填充DataGridView,而用户仍可以与UI交互?

Surely there must somehow be a way to populate a DataGridView entirely asynchronously while the user can still interact with the UI?

推荐答案


肯定有某种方法可以完全异步地填充DataGridView,而用户仍然可以与UI交互?

Surely there must somehow be a way to populate a DataGridView entirely asynchronously while the user can still interact with the UI?

有很多方法可以完成。

如果要从中获取数据(无论是直接数据库连接; REST还是WCF调用)支持分页,那么您可以通过内联 async / await 获取数据页面,并为页面中返回的每个项目添加行。

If whatever it is you are fetching the data from (whether it be a direct database connection; REST or WCF call) supports paging, then you could fetch pages of data via inline async/await and add rows for each item returned in the page.

例如

// somewhere in your UI code

async Task LoadAsync(List<Page> pages)
{
    foreach (var page in pages)
    {
        var stuff = await service.GetMovieSalesPagedAsync (page);

        foreach (var item in stuff)
        {
            _dataGrid.Rows.Add (/* convert item then add it here  */);  
        }        
    }
}

这比说请求要快所有数据一口气,然后尝试为每个项目添加行。

This is faster than say requesting all the data in one go and then trying to add rows for each item. The latter would just block the UI.

上述方法的好处是代码是内联的,易于阅读。

The benefit of the above approach is that the code is inline and easier to read.

此技术适用于要显示大量数据且您想要最佳性能UI的情况-明智的。如果源不支持分页,它也很有用。

This technique is better for when there is a large amount of data to display and you want the best performance UI-wise. It's also useful if the source does not support paging.

在这里您可以生成任务,其任务是检索一次将一个页面(或一次全部)添加到数据中,然后将每个页面结果添加为 ConcurrentQueue<> ,以使UI线程受益。如果必须全部检索,则将结果手动分成页面。

Here you can spawn a Task whose job is to retrieve the data a page (or all at once) at a time, then add each page results to say a ConcurrentQueue<> for the benefit of the UI thread. If you have to retrieve all of it, then break the results into pages manually.

同时,在您的 Application.Idle 处理程序尝试将一项从队列中弹出,如果找到了一项,则将新项作为行添加到数据网格。现在,根据您的应用程序,您可以选择处理所有可用页面或等待下一个应用程序空闲事件。可能需要一些微调。等待下一个应用程序空闲,可以使您的应用程序具有良好的UI响应能力。

Meanwhile, in your Application.Idle handler try to pop an item off the queue and if one is found, add the new items as rows to the datagrid. Now depending on your app, you may choose to process all available pages or wait for the next application idle event. It might take a bit of fine tuning. Waiting for the next application idle allows your app to play nice with UI responsiveness.

这将导致逐渐填充数据网格,而不是一次填充所有数据网格。

This will cause the datagrid to be filled progressively rather than all at once.

此方法的缺点是代码不再是内联的。您有一个代码块负责获取和存储数据。另一个用于将其泵入UI。

A con of this approach is that the code is no longer inline. You have one block of code responsible for fetching and storing data; another for pumping it into the UI.

这篇关于从后台线程填充DataGridView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆