ReactiveUI 6 Async Command not working in background thread in WPF application

ViewModel

public class MyViewModel:ReactiveObject, IRoutableViewModel{
        private ReactiveList<string> _appExtensions; 

        public MyViewModel(IScreen screen){
            HostScreen = screen;
            AppExtensions = new ReactiveList<string>();

            GetApplicationExtensions =
                ReactiveCommand.CreateAsyncTask(x => _schemaService.GetApplicationExtensions()); // returns a Task<IEnumerable<string>>

            GetApplicationExtensions
                .ObserveOn(RxApp.MainThreadScheduler)
                .SubscribeOn(RxApp.TaskpoolScheduler)
                .Subscribe(p =>
                {
                    using (_appExtensions.SuppressChangeNotifications())
                    {
                        _appExtensions.Clear();
                        _appExtensions.AddRange(p);
                    }
                });

            GetApplicationExtensions.ThrownExceptions.Subscribe(
                ex => Console.WriteLine("Error during fetching of application extensions! Err: {0}", ex.Message));
        }

        // bound to a ListBox 
        public ReactiveList<string> AppExtensions
        {
            get { return _appExtensions; }
            set { this.RaiseAndSetIfChanged(ref _appExtensions, value); }
        } 

       public ReactiveCommand<IEnumerable<string>> GetApplicationExtensions { get; protected set; }
}

but has an idea <Button Command="{Binding GetApplicationExtensions}"></Button>.

implantation GetApplicationExtensions

    public async Task<IEnumerable<string>> GetApplicationExtensions()
    {
        IEnumerable<string> extensions = null;

        using (var client = new HttpClient())
        {
            client.BaseAddress = BaseAddress;
            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);

            var response = await client.GetAsync("applications");

            if (response.IsSuccessStatusCode)
            {
                var json = await response.Content.ReadAsStringAsync();
                extensions = JsonConvert.DeserializeObject<IEnumerable<string>>(json);

            }

        }
        return extensions;
    }

From everything that I read about ReactiveUI and all the examples that I saw (although there are very few for new versions 6.0+), this should make my asynchronous call (which makes an asynchronous HTTP request through HttpClient) run in the background thread and update ListBoxin my opinion when the results come back from it. However, this is not so - the user interface is blocked during an asynchronous call. What am I doing wrong?

UPDATE

If I wrapped my HTTP call in Task, then everything worked as intended - the user interface did not hang at all. So the new implementation of my service call is this:

    public Task<IEnumerable<string>> GetApplicationExtensions()
    {
        var extensionsTask = Task.Factory.StartNew(async () =>
        {
             IEnumerable<string> extensions = null;

             using (var client = new HttpClient())
             {
                 client.BaseAddress = BaseAddress;
                 client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", _accessToken);

                 var response = await client.GetAsync("applications");

                 if (response.IsSuccessStatusCode)
                 {
                     var json = await response.Content.ReadAsStringAsync();
                     extensions = JsonConvert.DeserializeObject<IEnumerable<string>>(json);

                 }

             }
             return extensions;
        }

        return extensionsTask.Result;
    }

, async ObserveOn SubscribeOn ReactiveCommand, , @PaulBetts suggestessted. , ReactiveCommand my view :

            GetApplicationExtensions =
                ReactiveCommand.CreateAsyncTask(x => _schemaService.GetApplicationExtensions()); // returns a Task<IEnumerable<string>>

            GetApplicationExtensions
                .Subscribe(p =>
                {
                    using (_appExtensions.SuppressChangeNotifications())
                    {
                        _appExtensions.Clear();
                        _appExtensions.AddRange(p);
                    }
                });
+4
2

_schemaService.GetApplicationExtensions()?

, , . , ReactiveCommand , , CPU async op, , .

SubscribeOn, ObserveOn, ReactiveCommand , . !

+1

 GetApplicationExtensions
            .ObserveOn(RxApp.MainThreadScheduler)
            .SubscribeOn(RxApp.TaskpoolScheduler)

 GetApplicationExtensions
            .SubscribeOn(RxApp.TaskpoolScheduler)
            .ObserveOn(RxApp.MainThreadScheduler)

ObserveOn SubscribeOn

-1

All Articles