Click here to Skip to main content
15,885,985 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello everyone, I have a problem with UI locking.


Why the UI is freezed? I think it shouldn't be until DownloadHotListAsync finish.

Thanks a lot.

What I have tried:

C#
private async void RetrieveHotlist(object sender, RoutedEventArgs e) //button click
        {
            await DownloadHotListAsync();
            if (_hotItems != null)
            {
                foreach (var hotItem in _hotItems)
                {
                    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(() => Settings.Hotlist.Add(hotItem)));
                }
            }
        }

        private ObservableCollection<HotItem> _hotItems;

        private async Task DownloadHotListAsync()
        {
            _hotItems = new ObservableCollection<HotItem>();
            await Task.Run(() =>
                {

                    try
                    {
                        var serv = "xxxxxx";
                        string connStr = Common.GetConStrEF(serv + "\\" + Common.DBLOGIN_INSTANCE,
                                                            Common.DBLOGIN_DBNAME, Common.DBLOGIN_USER, Common.DBLOGIN_PASSWORD);
                        var dataModel = new xxxDataModel(connStr);

                        foreach (var category in dataModel.SpecialNumberCategory)  //retrieving database CreateObjectSet<SpecialNumberCategory>("SpecialNumberCategory"); //ObjectContext
                        {
                            var item = new HotItem() {  Name = category.Name };

                            _hotItems.Add(item);

                        }
                    }
                    catch (Exception exception)
                    {
                        var baseException = exception.GetBaseException();

                        MessageBox.Show("Error\n\n" + exception.Message + "\n\n" + baseException.Message);
                    }
                });
        }
Posted
Updated 26-Apr-16 8:25am

Could I suggest a few changes? After the await statement in the button click handler you are back on the dispatcher thread so you don’t need the Dispatcher BeginInvoke stuff. It is generally not a good idea to try to martial the threads yourself, you will get in a tangle. Leave all that to the async method. Also, the way you deal with exceptions is incorrect. Any exception raised in an asynchronous method is only thrown when the data is read at the await statement. So your try block should be positioned around the await statement. It’s best to make the method that you wish to run asynchronously as self contained as possible. I would return a ObservableCollection<hotitem></hotitem> from it and refractor the method into a standalone method without the try/catch blocks. So you would end up with something like this.


”c#”
private ObservableCollection<HotItem> RetrieveHotList()
      {
          var _hotItems = new ObservableCollection<HotItem>();
          //..............

          return _hotItems;
      }

      private async Task<ObservableCollection<HotItem>> DownloadHotListAsync()
      {
          var _hotItems = new ObservableCollection<HotItem>();
          try
          {
              _hotItems = await Task.Run(() => RetrieveHotList());
          }
          catch (Exception ex)
          {
              //handle the exception
              //...............
          }
          return _hotItems;
      }
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900