Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Resolve async void usages #371

Merged
merged 1 commit into from
Oct 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -391,3 +391,12 @@ dotnet_diagnostic.SA1210.severity = suggestion
dotnet_diagnostic.CA1308.severity = none
# CS1587: XML comment is not placed on a valid language element
dotnet_diagnostic.CS1587.severity = none

# VSTHRD110: This one is bugged: https://github.com/microsoft/vs-threading/issues/899
dotnet_diagnostic.VSTHRD110.severity = none
# VSTHRD200: Use `Async` naming convention
dotnet_diagnostic.VSTHRD200.severity = none
# VSTHRD100: Avoid async void methods
dotnet_diagnostic.VSTHRD100.severity = error
# VSTHRD101: Avoid unsupported async delegates
dotnet_diagnostic.VSTHRD101.severity = error
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
Prefix your items with `(Template)` if the change is about the template and not the resulting application.

## 2.1.X
- Replace local `DispatcherQueue` extension methods with the ones from the WinUI and Uno.WinUI Community Toolkit.
- Add `Microsoft.VisualStudio.Threading.Analyzers` to check for async void usages and fix async void usages.
- Enable `TreatWarningsAsErrors` for the Access, Business, and Presentation projects.
- Update analyzers packages and severity of rules.

Expand Down
2 changes: 2 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<!-- Microsoft.VisualStudio.Threading.Analyzers has the async void analyzers. -->
<PackageReference Include="Microsoft.VisualStudio.Threading.Analyzers" Version="17.5.22" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
<PackageReference Include="Nventive.View.Uno.WinUI" Version="0.5.0-dev.62" />
<PackageReference Include="Reactive.Annex.Uno.WinUI" Version="0.6.0-dev.50" />
<PackageReference Include="ReviewService.NativePrompters" Version="1.0.0" />
<PackageReference Include="Uno.CommunityToolkit.WinUI" Version="7.1.100" />
<PackageReference Include="Uno.Material.WinUI" Version="3.0.40" />
<PackageReference Include="Uno.Microsoft.Xaml.Behaviors.Interactivity.WinUI" Version="2.3.1-uno.2" />
<PackageReference Include="Uno.Microsoft.Xaml.Behaviors.WinUI.Managed" Version="2.3.1-uno.2" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ public static class ObservableExtensions2
/// <param name="delay">Time delay</param>
/// <param name="scheduler">Scheduler</param>
/// <returns>Output observable</returns>
[SuppressMessage("nventive.Globalization", "NV2005:NV2005 - Simple cyclomatic complexity​​", Justification = "Imported code")]
[SuppressMessage("nventive.Reliability", "NV0016:NV0016 - Do not create an async void lambda expression", Justification = "Imported code")]
[SuppressMessage("Usage", "VSTHRD101:Avoid unsupported async delegates", Justification = "Imported code")]
public static IObservable<T> ThrottleOrImmediate<T>(this IObservable<T> source, TimeSpan delay, IScheduler scheduler)
{
// Throttle behavior:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,6 @@ public class DadJokesFiltersPageViewModel : ViewModel
{
public DadJokesFiltersPageViewModel()
{
var pt = this.GetService<IDadJokesService>().GetAndObservePostTypeFilter();
var postType = GetPostType(pt);

PostTypeFilter = postType.Result;

async Task<PostTypes> GetPostType(ReplaySubject<PostTypes> ptArg)
{
return await ptArg.FirstAsync();
}
}

public IDynamicCommand HandleCheck => this.GetCommand((string pt) =>
Expand All @@ -40,7 +31,7 @@ async Task<PostTypes> GetPostType(ReplaySubject<PostTypes> ptArg)

public PostTypes PostTypeFilter
{
get => this.Get<PostTypes>(initialValue: PostTypes.Hot);
get => this.GetFromTask<PostTypes>(ct => this.GetService<IDadJokesService>().GetAndObservePostTypeFilter().FirstAsync(ct), initialValue: PostTypes.Hot);
set => this.Set(value);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ public string SelectedKey
ConfigurationValue = this.GetService<IConfiguration>()[value];

// Erase the selection from the ComboBox because we put it in the TextBox.
Task.Run(() => RaisePropertyChanged(nameof(SelectedKey)));
_ = Task.Run(() => RaisePropertyChanged(nameof(SelectedKey)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@
<Compile Include="$(MSBuildThisFileDirectory)Framework\Version\VersionProvider.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\AppBarBackButton.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\DependencyObjectExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\DispatcherQueueExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\FrameworkElementExtension.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Helpers\ObservableExtensions.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Shell.xaml.cs">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Text;
using CommunityToolkit.WinUI;
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
Expand Down Expand Up @@ -196,7 +197,7 @@ private static void FormatText(TextBox textbox, string textFormat)
return;
}

_ = textbox.DispatcherQueue.RunAsync(DispatcherQueuePriority.Normal, () =>
_ = textbox.DispatcherQueue.EnqueueAsync(() =>
{
textbox.Text = formattedText;
textbox.SelectionStart = selectionStart;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using System.Windows.Input;
using Chinook.DynamicMvvm;
using Chinook.SectionsNavigation;
using CommunityToolkit.WinUI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.UI.Dispatching;
Expand Down Expand Up @@ -77,7 +78,7 @@ private IDisposable ObserveBackButtonVisibility()
void OnStateChanged(bool canNavigateBackOrCloseModal)
{
var dispatcherQueue = ServiceProvider.GetRequiredService<DispatcherQueue>();
_ = dispatcherQueue.RunAsync(DispatcherQueuePriority.Normal, UpdateBackButtonUI);
_ = dispatcherQueue.EnqueueAsync(UpdateBackButtonUI);

void UpdateBackButtonUI() // Runs on UI thread.
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using Microsoft.UI.Dispatching;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using CommunityToolkit.WinUI;

namespace ApplicationTemplate;

Expand Down Expand Up @@ -78,7 +79,7 @@ private void OnPropertyNamedChanged()

private void OnErrorsChanged(object sender, DataErrorsChangedEventArgs e)
{
_ = DispatcherQueue.RunAsync(DispatcherQueuePriority.Normal, ErrorsChangedUI);
_ = DispatcherQueue.EnqueueAsync(ErrorsChangedUI);

void ErrorsChangedUI()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Microsoft.UI.Dispatching;
using CommunityToolkit.WinUI;
using Microsoft.UI.Dispatching;

namespace ApplicationTemplate;

Expand All @@ -13,7 +14,7 @@ public ExtendedSplashscreenController(DispatcherQueue dispatcherQueue)

public void Dismiss()
{
_ = _dispatcherQueue.RunAsync(DispatcherQueuePriority.Normal, DismissSplashScreen);
_ = _dispatcherQueue.EnqueueAsync(DismissSplashScreen);

void DismissSplashScreen() // Runs on UI thread.
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Threading.Tasks;
using CommunityToolkit.WinUI;
using Microsoft.UI.Dispatching;

namespace ApplicationTemplate;
Expand All @@ -15,37 +16,15 @@ public LauncherService(DispatcherQueue dispatcherQueue)

public async Task Launch(Uri uri)
{
var launchSucceeded = await DispatcherRunTaskAsync(DispatcherQueuePriority.Normal, async () => await Windows.System.Launcher.LaunchUriAsync(uri));
var launchSucceeded = await _dispatcherQueue.EnqueueAsync(InnerLaunch, DispatcherQueuePriority.Normal);
if (!launchSucceeded)
{
throw new LaunchFailedException($"Failed to launch URI: {uri}");
}
}

/// <summary>
/// This method allows for executing an async Task with result on the <see cref="DispatcherQueue"/>.
/// </summary>
/// <typeparam name="TResult">The <see cref="DispatcherQueue"/> result type.</typeparam>
/// <param name="dispatcherQueuePriority"><see cref="DispatcherQueuePriority"/>.</param>
/// <param name="asyncFunc">A function that will be execute on the <see cref="DispatcherQueue"/>.</param>
/// <returns><see cref="Task"/> of <typeparamref name="TResult"/>.</returns>
private async Task<TResult> DispatcherRunTaskAsync<TResult>(DispatcherQueuePriority dispatcherQueuePriority, Func<Task<TResult>> asyncFunc)
{
var completion = new TaskCompletionSource<TResult>();
await _dispatcherQueue.RunAsync(dispatcherQueuePriority, RunActionUI);
return await completion.Task;

async void RunActionUI()
async Task<bool> InnerLaunch()
{
try
{
var result = await asyncFunc();
completion.SetResult(result);
}
catch (Exception exception)
{
completion.SetException(new LaunchFailedException("An error occured while trying to launch an URI on the UI thread.", exception));
}
return await Windows.System.Launcher.LaunchUriAsync(uri);
}
}
}
Loading