uno.extensions
uno.extensions copied to clipboard
"async void" in a Model class breaks the build
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:
- Create a new Uno project with all of the default settings
- Get a successful build (just to be sure)
- In MainModel.cs, add this: public async void WhateverFunctionName() { await Task.Delay(1); }
- DO NOT ADD ANY CODE THAT CALLS THIS NEW METHOD
- 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.