Search code examples
c#event-dispatch-threaduno

Uno Platform sample Cat API doesn't work in Windows


I'm going step by step the Cat API sample of Uno Platform (https://github.com/unoplatform/uno/blob/master/doc/articles/howto-consume-webservices.md)

However, I have Dispatcher null in the following piece of code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.UI.Dispatching;

namespace TheCatApiClient.Models.ViewModels
{
    public abstract class DispatchedBindableBase : INotifyPropertyChanged
    {
        // Insert variables below here
        protected DispatcherQueue Dispatcher => DispatcherQueue.GetForCurrentThread();

        // Insert variables below here
        public event PropertyChangedEventHandler? PropertyChanged;

        // Insert SetProperty below here
        protected virtual bool SetProperty<T>(ref T backingVariable, T value, [CallerMemberName] string? propertyName = null)
        {
            if (EqualityComparer<T>.Default.Equals(backingVariable, value)) return false;

            backingVariable = value;
            RaisePropertyChanged(propertyName);

            return true;
        }

        // Insert RaisePropertyChanged below here
        protected void RaisePropertyChanged([CallerMemberName] string? propertyName = null)
        {
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
            DispatchAsync(() => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)));
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
        }

        // Insert DispatchAsync below here
        protected async Task DispatchAsync(DispatcherQueueHandler callback)
        {
            var hasThreadAccess =
#if __WASM__
        true;
#else
            Dispatcher.HasThreadAccess;
#endif

            if (hasThreadAccess)
            {
                callback.Invoke();
            }
            else
            {
                var completion = new TaskCompletionSource();
                Dispatcher.TryEnqueue(() =>
                {
                    callback();
                    completion.SetResult();
                });
                await completion.Task;
            }
        }
    }

I tried https://stackoverflow.com/a/69916469 it works once and then again the Dispatcher is null.

However, the WASM version works well (I'm not sure if it uses Dispatcher or not) but the Windows version is not.


Solution

  • I am not sure if it is a good approach or not, but trying the assignment worked for me:

     protected DispatcherQueue Dispatcher => DispatcherQueue.GetForCurrentThread();
    

    to

     protected DispatcherQueue Dispatcher = DispatcherQueue.GetForCurrentThread();