ObjectListView经过的时间列可能需要多线程 [英] ObjectListView elapsed time column Potentially needs Multi-Threading

查看:113
本文介绍了ObjectListView经过的时间列可能需要多线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我首先要提到我是编程新手.我将尽我所能解释我的问题和问题.

I should first mention I am new to programming. I will explain my problem and my question to the best of my ability.

我想知道是否有可能更新ObjectListView的单个列(从此处称为OLV).我想要的是一列显示每行的经过时间".此经过的时间"列将每15到30秒刷新一次.

I was wondering if it is possible to update a single column of an ObjectListView (from here on referred to as OLV). What I would like is to have a column that would display the "Elapsed Time" of each row. This Elapsed Time column would be refreshed every 15 to 30 seconds.

我如何设置我的OLV

How I set my OLV

myOLV.SetObjects(GetMyList());

GetMyList方法返回一个通过简单数据库查询填充的列表.

GetMyList method returns a list populated from a simple database query.

在GetMyList方法中,它将把DateTime列转换为显示经过时间的字符串.然后,OLV将其显示为字符串,而不是日期时间...

Within the GetMyList method, it would convert the DateTime column into a string showing the elapsed time. This is then shown by the OLV as a string, not a datetime...

elapsed_time = ((TimeSpan)(DateTime.Now - x.time_arrived)).ToString("hh\\:mm\\:ss");

我要如何通过使用计时器,使每30秒重新调用GetMyList方法,来完成这项工作.由于该方法将重新查询数据库并返回其检索到的记录,因此它们是最新的.直到我在OLV中有20行以上为止,此方法均能正常工作. 200行的每个刷新"都需要4秒钟才能完成.用户界面无响应的时间是4秒钟...

How I was trying to make this work was by using a timer that would every 30 seconds recall the GetMyList method. Because the method would re-query the database and return the records it retrieved, they were more up to date. This worked fine until I had more than 20 rows in the OLV. Each "refresh" for 200 rows takes 4 seconds to complete. That is 4 seconds that the UI is unresponsive...

由于我是编程新手,所以我从来没有对多线程做任何事情,但是我做了一些阅读,然后尝试创建一个解决方案.即使我创建了一个新线程来刷新" OLV对象,它仍然会导致整个表单无响应.

As I am new to programming, I have never done anything with multi-threading, but I did a little reading up on it and attempted to create a solution. Even when I create a new thread to "refresh" the OLV object, it still causes the entire form to become unresponsive.

我的问题,如何在每15-30秒刷新一次ObjectListView中的列,而又不会导致整个UI变得无响应? 在后台刷新ObjectListView并在准备好后显示它甚至是一个好主意吗?

My question is, how can I have a column within my ObjectListView refresh every 15-30 seconds without causing the entire UI to become unresponsive? Is it even possible/ a good idea to have the ObjectListView refresh in the background and then display it when it's ready?

推荐答案

问题是数据库查询的运行时间,而不是ObjectListView的更新(在ObjectListView中更新200行应花费大约200ms).您需要使数据库工作脱离UI线程并进入后台线程.然后,该后台线程可以定期从数据库中获取更新的数据.拥有更新的数据后,更新ObjectListView的速度非常快.

The problem is the run time of the database query, not the updating of ObjectListView (updating 200 rows in ObjectListView should take about 200ms). You need to get the database work off the UI thread and onto a background thread. That background thread can then periodically fetch the updated data from the database. Once you have the updated data, updating ObjectListView is very fast.

但是,多线程是一个很深的话题,很可能会咬你.有很多事情可能出错.您最好在UI上有一个按钮,用户可以单击该按钮以刷新网格并同步运行所有内容.同步版本运行正常后,就可以开始使用容易出错的多线程版本了.

However, multi-threading is a deep-dive topic that is likely to bite you. There are many things that can go wrong. You would be better off having a button on your UI that the user can click to Refresh the grid, and running everything synchronously. Once the synchronous version is working perfectly, then start working on the much more error prone multi-threaded version.

要严格回答您的问题,您需要执行以下操作:

To strictly answer your question, you would do something like this:

var thread = new Thread(_ => {
    while (!_cancelled) {
        Thread.Sleep(15 * 1000);
        if (!_cancelled) {
            var results = QueryDatabase();
            this.objectListView1.SetObjects(results);
        }
    }
});
thread.Start();

_cancelled是您的类中的布尔变量,可让您取消查询过程. QueryDatabase()是您用于获取新数据的方法.

_cancelled is a boolean variable in your class that allows you to cancel the querying process. QueryDatabase() is your method that fetches the new data.

此示例不处理错误,这是后台线程的重要问题.

This example doesn't deal with errors, which are a significant issue from background threads.

另一个难题是,大多数UI组件无法从后台线程进行更新,但是,ObjectListView有一些线程安全的方法,而SetObjects()是其中之一,因此您可以这样调用它.

Another gotcha is that most UI components cannot be updated from a background thread, however, ObjectListView has a few methods that are thread-safe and SetObjects() is one of them so you can call it like this.

只需重复一遍:您确实应该从同步版本开始,并且只有在对异步版本感到满意之后才开始考虑异步.

Just to repeat: you really should start with the synchronous version, and only start thinking about async once you are happy with that one.

这篇关于ObjectListView经过的时间列可能需要多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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