2014-09-29 2 views
0

Я должен сначала упомянуть, что я новичок в программировании. Я объясню свою проблему и мой вопрос в меру своих возможностей.Столбец прошедшего времени ObjectListView Потенциально необходимо многопоточность

Мне было интересно, если можно обновить один столбец ObjectListView (отсюда ОЛВ). Я хотел бы иметь столбец, который отображает «Истекшее время» каждой строки. Этот столбец прошедшего времени будет обновляться каждые 15-30 секунд.

Как я могу установить OLV

myOLV.SetObjects(GetMyList()); 

метод GetMyList возвращает список заполняется из простого запроса к базе данных.

В методе GetMyList он преобразует столбец DateTime в строку, показывающую прошедшее время. Затем это показано OLV в виде строки, а не даты и времени ...

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

Как я пытался сделать эту работу был с помощью таймера, который будет каждые 30 секунд вспомнить метод GetMyList. Поскольку метод будет повторно запрашивать базу данных и возвращать полученные записи, они были более актуальными. Это работало нормально, пока у меня не было более 20 строк в OLV. Каждое «обновление» для 200 строк занимает 4 секунды. Это составляет 4 секунды, когда пользовательский интерфейс не отвечает ...

Поскольку я новичок в программировании, я никогда ничего не делал с многопоточными работами, но я немного прочитал об этом и попытался создать решение. Даже когда я создаю новый поток, чтобы «обновить» объект OLV, он по-прежнему приводит к тому, что вся форма становится невосприимчивой.

Мой вопрос:, как я могу иметь столбец в моем обновлении ObjectListView каждые 15-30 секунд, не заставляя весь пользовательский интерфейс не реагировать? Возможно ли вообще быть/рекомендуется обновить ObjectListView в фоновом режиме, а затем отобразить его, когда он будет готов?

ответ

2

Проблема - это время выполнения запроса базы данных, а не обновление ObjectListView (обновление 200 строк в ObjectListView должно занимать около 200 мс). Вам нужно получить работу базы данных из потока пользовательского интерфейса и на фоновый поток. Этот фоновый поток может затем периодически извлекать обновленные данные из базы данных. После обновления данных обновление ObjectListView происходит очень быстро.

Однако многопоточность - это тема глубокой погружения, которая может вас укусить. Есть много вещей, которые могут пойти не так. Вам будет лучше иметь кнопку на вашем пользовательском интерфейсе, которую пользователь может щелкнуть, чтобы обновить сетку, и запустить все синхронно. Как только синхронная версия работает отлично, начните работу над гораздо более подверженной ошибкам многопоточной версией.

Строго ответить на ваш вопрос, вы могли бы сделать что-то вроде этого:

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

_cancelled является булевой переменной в классе, что позволяет отменить процесс запросов. QueryDatabase() - это ваш метод, который извлекает новые данные.

В этом примере не рассматриваются ошибки, которые являются существенной проблемой из фоновых потоков.

Еще одна проблема заключается в том, что большинство компонентов пользовательского интерфейса не могут быть обновлены из фонового потока, однако ObjectListView имеет несколько методов, которые являются потокобезопасными, и SetObjects() является одним из них, поэтому вы можете назвать это следующим образом.

Просто повторите: вы действительно должны начать с синхронной версии и только начинать думать об асинхронном режиме, когда вы довольны этим.

Смежные вопросы