Search code examples
c#.net.net-coresignalrtizen

.NET Tizen and SignalR


I am building a Tizen App (.NET Tizen 4.0) using .NET Core and Xamarin (https://docs.tizen.org/application/dotnet/).

Everything works perfectly fine, except for one thing. It is impossible to start an SignalR (Microsoft.AspNetCore.SignalR.Client (5.0.7)) connection to a hub. As soon as I create a new HubConnectionBuilder the following exception gets thrown:

System.IO.FileLoadException: Could not load file or assembly 'System.Threading.Tasks.Extensions, Version=4.2.0.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'. The located assembly's manifest definition does not match the assembly reference. (Exception from HRESULT: 0x80131040)

The weirdest part about this. This exception changes without me doing anything. If I grab a drink for example, come back and run it again a different assembly is missing. For now I saw either System.Threading.Tasks.Extensions, Version=4.2.0.1 or Microsoft.Extensions.DependencyInjection.Abstractions, Version=5.0.0 missing. To top it off: I do not use either of those packages actively.

So basically, as soon as I remove the following line of code, everything works fine.

this.hub = new HubConnectionBuilder().WithUrl($"wss://{Settings.Instance.ServerAddress}/deviceHub").Build();

I already tried to add the missing packages, but without success. The thing is, the packages, for some super strange reason, cannot be found in the SignalR.Client package (just my guess). I also tried removing SignalR.Client, Rebuilding the Project, Uninstalling Tizen from Visual Studio, Update all my packages and even uninstalled Visual Studio. I literally wasted my last 3 days on this without any progress. Maybe someone has a solution to this, or some sort of workaround.


Solution

  • The error might be due to the notorious assembly version mismatch problem on Tizen devices.

    https://developer.samsung.com/tizen/blog/en-us/2020/02/17/assembly-loading-problem-in-tizen-net-applications

    Explanation: Tizen 4.0 devices come with the pre-installed System.Threading.Tasks.Extensions.dll assembly of the version 4.1.1.0, but the latest Microsoft.AspNetCore.SignalR.Client nuget package depends on System.Threading.Tasks.Extensions.dll of 4.2.1.0. So the app will break because the runtime host always resolves the pre-installed assembly first. (The same app will run without problem on Tizen 5.5 devices because the pre-installed assembly version is 4.3.1.0.) However, I'm not sure why Microsoft.Extensions.DependencyInjection.Abstractions.dll couldn't be resolved since it's not part of the .NET Core runtime and not pre-installed with Tizen devices.

    In short, you may add the following event handler your app's Main() and check if the problem persists.

    static void Main(string[] args)
    {
        AppDomain.CurrentDomain.AssemblyResolve += (object s, ResolveEventArgs eventArgs) =>
        {
            var appDir = Path.GetDirectoryName(typeof(App).Assembly.Location);
            var assemblyName = eventArgs.Name.Split(',')[0];
            var assemblyPath = Path.Combine(appDir, assemblyName + ".dll");
            return File.Exists(assemblyPath) ? Assembly.LoadFile(assemblyPath) : null;
        };
        ..
        app.Run(args);
    }
    

    Please make sure the http://tizen.org/metadata/prefer_dotnet_aot metadata value is not set in tizen-manifest.xml when applying this change. If it's set, you need to change assemblyPath to something like Path.Combine(appDir, ".native_image", assemblyName + ".ni.dll").

    Please let me know if this doesn't fix your error.