Как правильно обновить данные в сетке, используя Task в WPF - PullRequest
0 голосов
/ 02 мая 2019

Мой маленький код WPF дает мне эту ошибку Вызывающий поток не может получить доступ к этому объекту, потому что другой поток владеет им Я знаю, что именно он говорит, но я не могу понять, как я могу это исправить.Я пробовал разные вещи, но не повезло, и я признаю, что я не очень хорош в библиотеке задач.

Это то, чего я пытаюсь достичь.

  1. Загрузка данных при загрузке формы WPF- Это нормально
  2. В форме пользователь нажимает кнопку Обновить , чтобы обновить данные из базы данных.

здесьмой код

public partial class DocListView : UserControlListBase
{
    private ScecoBillDataScope _scecoBillDataScope;
    public EntityCollection<ScecoBillEntity> ScecoBills = new EntityCollection<ScecoBillEntity>();

   public DocListView()
    {
        InitializeComponent();
        LoadData();
    }


   private async void LoadData()
    {
        await Task.Run(() =>
        {

            _scecoBillDataScope.FetchData();
        });
        var collectionView = CollectionViewSource.GetDefaultView(_scecoBillDataScope.ScecoBills);

        await Dispatcher.BeginInvoke(new ThreadStart(()=> LayoutRoot.DataContext = collectionView));

     }

  private void BbiRefresh_ItemClick(object sender, DevExpress.Xpf.Bars.ItemClickEventArgs e)
    {
        _scecoBillDataScope.Reset();
        LoadData();
        e.Handled = true;
    }}

На самом деле ошибка появляется, когда я нажимаю кнопку Обновить в этой строке _scecoBillDataScope.FetchData (); Пожалуйста, советуйте.

Ответы [ 3 ]

1 голос
/ 03 мая 2019

Ваша проблема в этой строке:

await Dispatcher.BeginInvoke(new ThreadStart(()=> LayoutRoot.DataContext = collectionView));

Вы просто создаете новый поток, вам нужно фактически отправить поток в GUI:

Application.Current.Dispatcher.Invoke(() =>
{
    LayoutRoot.DataContext = collectionView;
});
0 голосов
/ 06 мая 2019

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

Попробуйте загрузить новую коллекцию из Task.Run, а затем скопировать их поверх существующих элементов.в то время как в потоке пользовательского интерфейса.Итак, новая коллекция построена на потоке пула потоков (Task.Run), а затем элементы коллекции с привязкой к данным изменяются из потока пользовательского интерфейса.

0 голосов
/ 03 мая 2019

Похоже, вы хотите что-то сделать в потоке пользовательского интерфейса.

Как Вы знаете, Вы можете использовать Dispatcher класс.

Но есть и другой способ спросить что-то в теме пользовательского интерфейса.

var uiThread = TaskScheduler.FromCurrentSynchronizationContext();

Task.Factory.StartNew(() =>
{
    // I assumed that It returns boolean value
    _scecoBillDataScope.FetchData();
}).ContinueWith(x =>
{
    // Here you can put the code to work on the UI thread.
    if (x.Result)
    {
          var collectionView = CollectionViewSource.GetDefaultView(_scecoBillDataScope.ScecoBills);
          LayoutRoot.DataContext = collectionView;
    }

}, uiThread);

Надеюсь, это поможет.

спасибо.

...