【问题标题】:ObjectListView elapsed time column Potentially needs Multi-ThreadingObjectListView 已用时间列 可能需要多线程
【发布时间】:2014-11-24 06:43:44
【问题描述】:

我应该首先提到我是编程新手。我会尽我所能解释我的问题和我的问题。

我想知道是否可以更新 ObjectListView 的单个列(从这里称为 OLV)。我想要的是有一列可以显示每行的“经过时间”。此 Elapsed Time 列将每 15 到 30 秒刷新一次。

我如何设置我的 OLV

myOLV.SetObjects(GetMyList());

GetMyList 方法返回一个从简单数据库查询中填充的列表。

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

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

我尝试通过使用每 30 秒调用一次 GetMyList 方法的计时器来完成这项工作。因为该方法将重新查询数据库并返回它检索到的记录,所以它们是最新的。这一直很好,直到我在 OLV 中有超过 20 行。 200 行的每次“刷新”需要 4 秒才能完成。即 UI 无响应的 4 秒...

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

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

【问题讨论】:

    标签: c# multithreading winforms objectlistview


    【解决方案1】:

    问题是数据库查询的运行时间,而不是 ObjectListView 的更新(更新 ObjectListView 中的 200 行大约需要 200 毫秒)。您需要让数据库工作脱离 UI 线程并进入后台线程。然后,该后台线程可以定期从数据库中获取更新的数据。一旦你有了更新的数据,更新 ObjectListView 会非常快。

    但是,多线程是一个很深奥的话题,很可能会让您感到厌烦。有很多事情可能会出错。您最好在 UI 上设置一个按钮,用户可以单击该按钮来刷新网格,并同步运行所有内容。一旦同步版本完美运行,然后开始处理更容易出错的多线程版本。

    要严格回答您的问题,您可以这样做:

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

    _cancelled 是您的类中的一个布尔变量,允许您取消查询过程。 QueryDatabase() 是获取新数据的方法。

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

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

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

    【讨论】:

      猜你喜欢
      • 2016-03-21
      • 2012-07-20
      • 1970-01-01
      • 2011-06-02
      • 1970-01-01
      • 2011-02-23
      • 1970-01-01
      • 1970-01-01
      • 2010-10-02
      相关资源
      最近更新 更多