unoplatform / uno.extensions

Libraries to ease common developer tasks associated with building multi-platform mobile, desktop and web applications using Uno Platform or WinAppSDK.
https://platform.uno/
Other
74 stars 47 forks source link

[Windows][ThemeService] Navigating to a page then accessing IsDark produces a COMException #2334

Open rajamatt opened 5 months ago

rajamatt commented 5 months ago

Current behavior

The ThemeService injection seems to have a problem.

Navigating to a page that isn't the first page produces a COMException if we try to access the IsDark property of the service.

ThemeServiceCOMException

How to reproduce it (as minimally and precisely as possible)

1) Create new unoapp with recommended preset. 2) Add the ThemeService Uno feature and the .UseThemeService() for the app host. 3) On the SecondModel, setup a typical service injection for IThemeService. 4) Try to access themeService.IsDark in the code.

Minimal repro app: ThemeTest.zip

Environment

Package Version(s):

Uno.Sdk 5.2.132, but also happens with 5.2.161

<UnoExtensionsVersion>4.1.23</UnoExtensionsVersion>
<UnoToolkitVersion>6.0.24</UnoToolkitVersion>
<UnoThemesVersion>5.0.13</UnoThemesVersion>
<UnoCSharpMarkupVersion>5.2.14</UnoCSharpMarkupVersion>

Affected platform(s):

Visual Studio:

Relevant plugins:

Anything else we need to know?

Xiaoy312 commented 5 months ago
System.Runtime.InteropServices.COMException
  HResult=0x8001010E
  Message=
  Source=WinRT.Runtime
  StackTrace:
   at WinRT.ExceptionHelpers.<ThrowExceptionForHR>g__Throw|39_0(Int32 hr) in WinRT\ExceptionHelpers.cs:line 146
^ 0x8001010E=RPC_E_WRONG_THREAD 

call stack:
    WinRT.ExceptionHelpers.ThrowExceptionForHR.__Throw|39_0(int hr) Line 146    C#
    ABI.Microsoft.UI.Xaml.IFrameworkElementMethods.get_ActualTheme(WinRT.IObjectReference _obj) Line 118    C#
>   Microsoft.UI.Xaml.FrameworkElement.ActualTheme.get() Line 175   C#
    Uno.Extensions.Toolkit.ThemeService.IsDark.get()    Unknown

looks like you need the ui-thread to access this property:

public SecondModel(IThemeService themeService, IDispatcher dispatcher) {
      _themeService = themeService;

      //var isDark = _themeService.IsDark; // COMException
      _ = dispatcher.TryEnqueue(() => {
          var isDark = _themeService.IsDark; // ok
      });
jeromelaban commented 5 months ago

This looks like it is not an issue, unless we want to change the themeservice to be threading compatible.