uno.extensions icon indicating copy to clipboard operation
uno.extensions copied to clipboard

"async void" in a Model class breaks the build

Open LegacyNsfw opened this issue 10 months ago • 0 comments

Current behavior

See repro steps.

Expected behavior

A clean build.

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

See the AsyncVoid branch of this repo: https://github.com/LegacyNsfw/UnoExample-1/tree/AsyncVoid

Repro steps:

  1. Create a new Uno project with all of the default settings
  2. Get a successful build (just to be sure)
  3. In MainModel.cs, add this: public async void WhateverFunctionName() { await Task.Delay(1); }
  4. DO NOT ADD ANY CODE THAT CALLS THIS NEW METHOD
  5. Build again

Results:

\obj\Debug\net8.0-desktop\Uno.Extensions.Reactive.Generator\Uno.Extensions.Reactive.Generator.FeedsGenerator\UnoExample.Presentation.MainModel.Bindable.g.cs(69,8,69,46): error CS4008: Cannot await 'void'

The same error is repeated for each of the targets (browser, android, ios, etc).

Apparently the code generator added code to call that new method.

Workaround

Using "async Task" is of course preferred to "async void" but please see the notes below.

Works on UWP/WinUI

None

Environment

No response

NuGet package version(s)

No response

Affected platforms

No response

IDE

Visual Studio 2022

IDE version

Version 17.12.3

Relevant plugins

Uno platform extension 1.0

Anything else we need to know?

Yes I am aware that "async void" is not a best practice. But, hear me out...

I ran into this when using a library that requires the application to implement callbacks through an interface that has void methods.

The most natural place to implement those methods is in a Model class, because the callbacks update the UI.

My implementation of those callbacks needs async.

So here I am doing something that is admittedly not a best practice - due to an interface defined by another library.

I don't think it's reasonable for Uno to be so draconian about enforcing "async Task" for methods that are not being invoked by anything at all. These methods were never going to be invoked by generated code. In the application, they were going to be invoked by the library that uses the interface for callbacks, but in the minimal repro repo the method in question is not being called by anything. Except, apparently, by generated code.

There's just no reason for the build to break due to the mere existence of an unused async void method.

Also, as with my previous bug report, the generated file was deleted by the build process, otherwise I'd include it here. Again, I think it's a mistake to delete those files.

LegacyNsfw avatar Jan 28 '25 07:01 LegacyNsfw