Search code examples
wpfmultithreadingasynchronouswindows-phone-8event-dispatching

Windows Phone 8 Dispatcher.BeginInvoke not working async


I am new to async programming and to WP8 , this is my first app and I have some issues with Dispatcher.BeginInvoke(..)

In my code behind the view class, i am trying to load data in a Pivot scree async for the second tab.

Here is what i have right now :

public partial class ReminderPivot : PhoneApplicationPage
    {
        #region Reminder Members
        private ReminderViewModel _model;
        private IRepository _repository;
        #endregion Reminder Members

        #region Constructors
        public ReminderPivot()
        {
            InitializeComponent();
            _model = new ReminderViewModel();
            _repository = new LocalStorageRepository();

            LoadData();
            LoadAsyncData();

            this.DataContext = _model;

        }
        #endregion Constructors

        public void LoadData()
        {
            IEnumerable<Reminder> activeList = _repository.GetRemindersByStatusId(2);
            if (activeList != null)
            {
                foreach (var reminder in activeList)
                {
                    _model.ActiveReminders.Add(reminder);
                }
            }
        }
        public void LoadAsyncData()
        {            
            Action action = () =>
            {
                Thread.Sleep(5000);

                IEnumerable<Reminder> inactiveList = _repository.GetRemindersByStatusId(3);
                if (inactiveList != null)
                {
                    _model.InctiveReminders = new System.Collections.ObjectModel.ObservableCollection<Reminder>(inactiveList);
                }
            };

           Dispatcher.BeginInvoke(action);
        }

The thing is that this STILL blocks my UI thread. What am i missing here?

EDIT : The idea is to load data async into the ViewModel ObservableCollection wich is ModelBinded in the XAML.

If i try to make the call async on another thread with Task.Factory(...) etc lets say, this crashes as i am changing the binding from another thread not UI thread.


Solution

  • After the suggestion of @PedroLamas i made it work, not sure if this is the nicest way or the most elegant but it gets the job done.

    Im making the call that takes time to complete on another thread with Task.Factory and making it awaitable, and at the end just update the UI with the Dispatcher.

    public async void LoadAsyncDataWithTask()
            {
                IEnumerable<Reminder> inactiveList = null;
                Action action = () =>
                {
                    Thread.Sleep(2000);
                    inactiveList = _repository.GetRemindersByStatusId(2);
                };
    
                await Task.Factory.StartNew(action);
    
                Action action2 = () =>
                {
                    if (inactiveList != null)
                    {
                        foreach(var item in inactiveList)
                        {
                            _model.InctiveReminders.Add(item);
                        }
                    }
                };
    
                Dispatcher.BeginInvoke(action2);
    
            }