question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Exception thrown when using CommunityToolkit and the cancellation token

See original GitHub issue

Describe the bug

I am trying to use the cancellation token as described in documentation here RelayCommand

[RelayCommand]
private async Task GreetUserAsync(CancellationToken token)
{
    try
    {
        User user = await userService.GetCurrentUserAsync(token);

        Console.WriteLine($"Hello {user.Name}!");
    }
    catch (OperationCanceledException)
    {
    }
}

However, whenever I add the cancellation token to the method - the program starts throwing the Object reference not set to an instance of an object exception when invoking the command.

To Reproduce Steps to reproduce the behavior:

  1. using .Net 6.0 Avalonia MVVM app on Windows 10 x64, CommunityToolkit.Mvvm v.8.1.0, rest of the information along with full repro code you will find in a repo https://github.com/pavlexander/avaloniaExceptionTest1

  2. Create fresh Avalogia app, add the community toolkit nuget package

  3. Add a new dummy window

  4. add 2 buttons to the main widnow.

  <StackPanel>
    <Button Command="{Binding OpenNewWindowWithToken}">Open new window (with CancellationToken)</Button>
    <Button Command="{Binding OpenNewWindow}">Open new window</Button>
  </StackPanel>
  1. create 2 commands in the main view model, one with cancellation token, one without
    [RelayCommand]
    public async Task OpenNewWindowWithToken(CancellationToken token)
    {
        var newWindow = new Window1();
        newWindow.Show();
    }

    [RelayCommand]
    public async Task OpenNewWindow()
    {
        var newWindow = new Window1();
        newWindow.Show();
    }
  1. Launch the app. First click on the button that uses command without cancellation token. Works Ok.
  2. Now click on the button that has cancellation token as an input parameter. Observe exception.

Stacktrace:

at Avalonia.Controls.Button.OnClick()\r\n at Avalonia.Controls.Button.OnPointerReleased(PointerReleasedEventArgs e)\r\n at System.Reactive.Subjects.Subject`1.OnNext(T value)\r\n at Avalonia.Interactivity.EventRoute.RaiseEventImpl(RoutedEventArgs e)\r\n at Avalonia.Interactivity.EventRoute.RaiseEvent(IInteractive source, RoutedEventArgs e)\r\n at Avalonia.Interactivity.Interactive.RaiseEvent(RoutedEventArgs e)\r\n at Avalonia.Input.MouseDevice.MouseUp(IMouseDevice device, UInt64 timestamp, IInputRoot root, Point p, PointerPointProperties props, KeyModifiers inputModifiers)\r\n at Avalonia.Input.MouseDevice.ProcessRawEvent(RawPointerEventArgs e)\r\n at Avalonia.Input.InputManager.ProcessInput(RawInputEventArgs e)\r\n at Avalonia.Win32.WindowImpl.AppWndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)\r\n at Avalonia.Win32.WindowImpl.WndProc(IntPtr hWnd, UInt32 msg, IntPtr wParam, IntPtr lParam)\r\n at Avalonia.Win32.Interop.UnmanagedMethods.DispatchMessage(MSG& lpmsg)\r\n at Avalonia.Win32.Win32Platform.RunLoop(CancellationToken cancellationToken)\r\n at Avalonia.Threading.Dispatcher.MainLoop(CancellationToken cancellationToken)\r\n at Avalonia.Controls.ApplicationLifetimes.ClassicDesktopStyleApplicationLifetime.Start(String[] args)\r\n at AvaloniaApplication2.Program.Main(String[] args) in C:\repos\avaloniaExceptionTest1\AvaloniaApplication2\Program.cs:line 14

Expected behavior I expect the method to work, no exceptions to be thrown, as documented.

Screenshots image

Desktop (please complete the following information):

  • OS: Windows 10 x64
  • Avalonia Version=“0.10.18”
  • Avalonia.Desktop Version=“0.10.18”
  • Microsoft Visual Studio Community 2022 (64-bit) - Current Version 17.4.3
  • CommunityToolkit.Mvvm v.8.1.0

Additional context I have originally reported this bug to CommunityToolkit github page https://github.com/CommunityToolkit/dotnet/issues/579, however, from the response of the toolkit maintainer I understood that the problem is within the Avalonia itself, rather than the toolkit… Hence this issue is essentialy a duplicate of what I have reported earlier.

The code that reproduces the problem is located in repo https://github.com/pavlexander/avaloniaExceptionTest1

Please let me know if some additional input is needed.

Issue Analytics

  • State:closed
  • Created 8 months ago
  • Comments:6 (4 by maintainers)

github_iconTop GitHub Comments

1reaction
Sergio0694commented, Jan 22, 2023

Here is a minimal repro, without the MVVM Toolkit at all:

using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Input;

namespace AvaloniaApplication2.ViewModels;

public partial class MainWindowViewModel
{
    private ICommand _OpenNewWindowWithTokenCommand;

    public ICommand OpenNewWindowWithTokenCommand => _OpenNewWindowWithTokenCommand ??= new AsyncRelayCommand2(OpenNewWindowWithToken);

    public async Task OpenNewWindowWithToken(CancellationToken token)
    {
    }
}

public sealed class AsyncRelayCommand2 : ICommand
{
    private readonly Func<CancellationToken, Task> cancelableExecute;
    public event EventHandler? CanExecuteChanged;

    public AsyncRelayCommand2(Func<CancellationToken, Task> cancelableExecute)
    {
        this.cancelableExecute = cancelableExecute;
    }

    public Task? ExecutionTask { get; private set; }

    public bool CanExecute(object? parameter)
    {
        return ExecutionTask is not { IsCompleted: false };
    }

    public async void Execute(object? parameter)
    {
        Task executionTask = ExecutionTask = this.cancelableExecute(default);

        CanExecuteChanged?.Invoke(this, EventArgs.Empty);

        await executionTask;
    }
}

If you change that Func<CancellationToken, Task> to Func<Task> and adjust the method signature accordingly, the issue goes away. No idea why that parameter is causing the issue, but hopefully this helps the investigation in Avalonia 🙂

0reactions
maxkatz6commented, Jan 25, 2023

I will close this issue, and open another more specific https://github.com/AvaloniaUI/Avalonia/issues/10075

Read more comments on GitHub >

github_iconTop Results From Across the Web

ThrowHelper.ThrowOperationCanceledException Method
The CancellationToken in use. Exceptions. OperationCanceledException. Thrown with the specified parameters. Applies to. Windows Community Toolkit 7.1.0 and ...
Read more >
Cancellation Token Doesn't throw exception
I'm having a problem exiting a task with the cancellation token. My program freezes when I get to the token2.ThrowIfCancellationRequested();.
Read more >
Canceling Async Commands Made Easy in Blazor with ...
If the CancellationToken is cancelled during the Task.Delay execution, it throws an OperationCanceledException . To handle this exception, ...
Read more >
A Deep Dive into C#'s CancellationToken | by Mitesh Shah
Listeners of the cancellation token can optionally throw this exception to verify the source of the cancellation and notify others that it has ......
Read more >
Speech recognition with .NET MAUI
recognitionResult, CancellationToken cancellationToken); } ... Context); if (speechRecognizer is null) { throw new ArgumentException("Speech ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found