Поток для обновления сетки данных - PullRequest
0 голосов
/ 23 января 2012

У меня есть окно с telerik gridview в нем, и я обновляю это gridview каждую 1 минуту.У меня есть метод обновления, и каждую 1 минуту я его вызываю.

Я не могу использовать BackgroundWorker, потому что мой CollectionViewSource находится в потоке пользовательского интерфейса, и фоновый работник не может его использовать.мой вопрос, как я могу вызвать этот метод обновления из другого потока?

где-то я вижу этот пример кода:

Application.Current.Dispatcher.BeginInvoke(new Action(() => this.Refresh()));

это истинный способ, которым я использую приведенный выше код в Refresh_Executed?Пожалуйста, помогите мне.

это мой метод обновления:

public ObservableCollection<RequestView> AllRequestsData { get; set; }

private void Refresh()
    {
        using (ArchiveEntities db = new ArchiveEntities())
        {
            var data = db.RequestSyncs.Where(x => x.UserId == null);
            if (data.Any())
            {
                string IdList = String.Join(",", data.Where(x => x.IsNew).Select(x => x.RequestId));
                if (!String.IsNullOrWhiteSpace(IdList))
                {
                    foreach (var item in db.RequestViews.Where("it.id in {" + IdList + "}"))
                    {
                        this.AllRequestsData.Add(item);
                    }
                }

                foreach (var item in data.Where(x => x.IsDeleted))
                {
                    RequestView rv = this.AllRequestsData.Where(x => x.Id == item.RequestId).SingleOrDefault();
                    if (rv != null)
                    {
                        this.AllRequestsData.Remove(rv);
                    }
                }

                foreach (var item in data)
                {
                    db.RequestSyncs.DeleteObject(item);
                }

                db.SaveChanges();
            }
        }
    }

спасибо

Ответы [ 3 ]

2 голосов
/ 23 января 2012

Да, использование Dispatcher является правильным способом выполнения большинства легких фоновых заданий.

Однако имейте в виду, что тяжелая фоновая работа, выполняемая на Dispatcher, может заблокировать пользовательский интерфейс, поскольку он все ещеработает в основном потоке пользовательского интерфейса.Если у вас большой объем обработки, я бы рекомендовал использовать BackgroundWorker, Task Parallel Library или какую-либо другую форму многопоточности (я предпочитаю await / async однако это доступно только в C # 5.0 или AsyncCTP Refresh )

Кроме того, я бы рекомендовал обновить коллекцию, к которой привязан DataGrid, а не сам DataGrid.Я думаю, что при обновлении DataGrid будут перерисованы все элементы пользовательского интерфейса, а при обновлении ItemsSource просто будут повторно использоваться существующие элементы пользовательского интерфейса, если это возможно.

1 голос
/ 23 января 2012

Может быть, в общем-то это и так, но это зависит от содержания метода Refresh, можете ли вы предоставить его содержимое?

РЕДАКТИРОВАТЬ Обычно я загружаю данные в поле зрениямодели с использованием асинхронных ссылок и не нужно обновлять RadGridView.Но когда, например, мне нужно свернуть все группы и т. Д., Я использую radGridView.Dispatcher.BeginInvoke (...).

ОБНОВЛЕНИЕ

Нет необходимостиобновление RadGridView.Вы обновляете это свойство ItemsSource.Я бы не рекомендовал использовать Dispatcher в такой ситуации, и я бы использовал Task Parallel Library для получения простых данных из базы данных и обновления ItemsSource с синхронизацией с текущим потоком пользовательского интерфейса:

Task.Factory.StartNew<IEnumerable<RequestSyncPlain>>(() =>
{
  return result;
}).ContinueWith(_ =>
{
  try
  {
    _.Wait();
  }
  catch (AggregateException ae)
  {
  }

  foreach (var requestSyncPlain in _.Result)
  {
    var requestSync = new RequestSyncViewModel(requestSyncPlain);

    requestSyncObservableCollection.Add(requestSync);
  }
}, TaskScheduler.FromCurrentSynchronizationContext());

Обратите внимание, что вам следует обновить этот метод для реализации ваших потребностей (вы могли бы поместить свои методы базы данных в первое задание и, возможно, вернуть Tuple из двух наборов), и это просто идея.

0 голосов
/ 23 января 2012

Использование TPL - лучший способ, когда дело доходит до многопоточности с момента выпуска .NET 4 ...

using System.Threading.Tasks;
Task.Factory.StartNew(() => this.Refresh())
...