AsyncAwaitBestPractices.MVVM
6.0.6
dotnet add package AsyncAwaitBestPractices.MVVM --version 6.0.6
NuGet\Install-Package AsyncAwaitBestPractices.MVVM -Version 6.0.6
<PackageReference Include="AsyncAwaitBestPractices.MVVM" Version="6.0.6" />
paket add AsyncAwaitBestPractices.MVVM --version 6.0.6
#r "nuget: AsyncAwaitBestPractices.MVVM, 6.0.6"
// Install AsyncAwaitBestPractices.MVVM as a Cake Addin
#addin nuget:?package=AsyncAwaitBestPractices.MVVM&version=6.0.6
// Install AsyncAwaitBestPractices.MVVM as a Cake Tool
#tool nuget:?package=AsyncAwaitBestPractices.MVVM&version=6.0.6
AsyncAwaitBestPractices.MVVM
Available on NuGet: https://www.nuget.org/packages/AsyncAwaitBestPractices.MVVM/
Allows for
Task
to safely be used asynchronously withICommand
:IAsyncCommand : ICommand
AsyncCommand : IAsyncCommand
IAsyncCommand<T> : ICommand
AsyncCommand<T> : IAsyncCommand<T>
IAsyncCommand<TExecute, TCanExecute> : IAsyncCommand<TExecute>
AsyncCommand<TExecute, TCanExecute> : IAsyncCommand<TExecute, TCanExecute>
Allows for
ValueTask
to safely be used asynchronously withICommand
:IAsyncValueCommand : ICommand
AsyncValueCommand : IAsyncValueCommand
IAsyncValueCommand<T> : ICommand
AsyncValueCommand<T> : IAsyncValueCommand<T>
IAsyncValueCommand<TExecute, TCanExecute> : IAsyncValueCommand<TExecute>
AsyncValueCommand<TExecute, TCanExecute> : IAsyncValueCommand<TExecute, TCanExecute>
Setup
- Available on NuGet: https://www.nuget.org/packages/AsyncAwaitBestPractices.MVVM/
- Add to any project supporting .NET Standard 1.0
AsyncCommand
Allows for Task
to safely be used asynchronously with ICommand
:
AsyncCommand<TExecute, TCanExecute> : IAsyncCommand<TExecute, TCanExecute>
IAsyncCommand<TExecute, TCanExecute> : IAsyncCommand<TExecute>
AsyncCommand<T> : IAsyncCommand<T>
IAsyncCommand<T> : ICommand
AsyncCommand : IAsyncCommand
IAsyncCommand : ICommand
public AsyncCommand(Func<TExecute, Task> execute,
Func<TCanExecute, bool>? canExecute = null,
Action<Exception>? onException = null,
bool continueOnCapturedContext = false)
public AsyncCommand(Func<T, Task> execute,
Func<object?, bool>? canExecute = null,
Action<Exception>? onException = null,
bool continueOnCapturedContext = false)
public AsyncCommand(Func<Task> execute,
Func<object?, bool>? canExecute = null,
Action<Exception>? onException = null,
bool continueOnCapturedContext = false)
public class ExampleClass
{
bool _isBusy;
public ExampleClass()
{
ExampleAsyncCommand = new AsyncCommand(ExampleAsyncMethod);
ExampleAsyncIntCommand = new AsyncCommand<int>(ExampleAsyncMethodWithIntParameter);
ExampleAsyncIntCommandWithCanExecute = new AsyncCommand<int, int>(ExampleAsyncMethodWithIntParameter, CanExecuteInt);
ExampleAsyncExceptionCommand = new AsyncCommand(ExampleAsyncMethodWithException, onException: ex => Console.WriteLine(ex.ToString()));
ExampleAsyncCommandWithCanExecuteChanged = new AsyncCommand(ExampleAsyncMethod, _ => !IsBusy);
ExampleAsyncCommandReturningToTheCallingThread = new AsyncCommand(ExampleAsyncMethod, continueOnCapturedContext: true);
}
public IAsyncCommand ExampleAsyncCommand { get; }
public IAsyncCommand<int> ExampleAsyncIntCommand { get; }
public IAsyncCommand<int, int> ExampleAsyncIntCommandWithCanExecute { get; }
public IAsyncCommand ExampleAsyncExceptionCommand { get; }
public IAsyncCommand ExampleAsyncCommandWithCanExecuteChanged { get; }
public IAsyncCommand ExampleAsyncCommandReturningToTheCallingThread { get; }
public bool IsBusy
{
get => _isBusy;
set
{
if (_isBusy != value)
{
_isBusy = value;
ExampleAsyncCommandWithCanExecuteChanged.RaiseCanExecuteChanged();
}
}
}
async Task ExampleAsyncMethod()
{
await Task.Delay(1000);
}
async Task ExampleAsyncMethodWithIntParameter(int parameter)
{
await Task.Delay(parameter);
}
async Task ExampleAsyncMethodWithException()
{
await Task.Delay(1000);
throw new Exception();
}
bool CanExecuteInt(int count)
{
if(count > 2)
return true;
return false;
}
void ExecuteCommands()
{
_isBusy = true;
try
{
ExampleAsyncCommand.Execute(null);
ExampleAsyncIntCommand.Execute(1000);
ExampleAsyncExceptionCommand.Execute(null);
ExampleAsyncCommandReturningToTheCallingThread.Execute(null);
if(ExampleAsyncCommandWithCanExecuteChanged.CanExecute(null))
ExampleAsyncCommandWithCanExecuteChanged.Execute(null);
if(ExampleAsyncIntCommandWithCanExecute.CanExecute(1))
ExampleAsyncIntCommandWithCanExecute.Execute(1);
}
finally
{
_isBusy = false;
}
}
}
AsyncValueCommand
Allows for ValueTask
to safely be used asynchronously with ICommand
.
If you're new to ValueTask, check out this great write-up, Understanding the Whys, Whats, and Whens of ValueTask.
AsyncValueCommand<TExecute, TCanExecute> : IAsyncValueCommand<TExecute, TCanExecute>
IAsyncValueCommand<TExecute, TCanExecute> : IAsyncValueCommand<TExecute>
AsyncValueCommand<T> : IAsyncValueCommand<T>
IAsyncValueCommand<T> : ICommand
AsyncValueCommand : IAsyncValueCommand
IAsyncValueCommand : ICommand
public AsyncValueCommand(Func<TExecute, ValueTask> execute,
Func<TCanExecute, bool>? canExecute = null,
Action<Exception>? onException = null,
bool continueOnCapturedContext = false)
public AsyncValueCommand(Func<T, ValueTask> execute,
Func<object?, bool>? canExecute = null,
Action<Exception>? onException = null,
bool continueOnCapturedContext = false)
public AsyncValueCommand(Func<ValueTask> execute,
Func<object?, bool>? canExecute = null,
Action<Exception>? onException = null,
bool continueOnCapturedContext = false)
public class ExampleClass
{
bool _isBusy;
public ExampleClass()
{
ExampleValueTaskCommand = new AsyncValueCommand(ExampleValueTaskMethod);
ExampleValueTaskIntCommand = new AsyncValueCommand<int>(ExampleValueTaskMethodWithIntParameter);
ExampleValueTaskIntCommandWithCanExecute = new AsyncValueCommand<int, int>(ExampleValueTaskMethodWithIntParameter, CanExecuteInt);
ExampleValueTaskExceptionCommand = new AsyncValueCommand(ExampleValueTaskMethodWithException, onException: ex => Debug.WriteLine(ex.ToString()));
ExampleValueTaskCommandWithCanExecuteChanged = new AsyncValueCommand(ExampleValueTaskMethod, _ => !IsBusy);
ExampleValueTaskCommandReturningToTheCallingThread = new AsyncValueCommand(ExampleValueTaskMethod, continueOnCapturedContext: true);
}
public IAsyncValueCommand ExampleValueTaskCommand { get; }
public IAsyncValueCommand<int> ExampleValueTaskIntCommand { get; }
public IAsyncCommand<int, int> ExampleValueTaskIntCommandWithCanExecute { get; }
public IAsyncValueCommand ExampleValueTaskExceptionCommand { get; }
public IAsyncValueCommand ExampleValueTaskCommandWithCanExecuteChanged { get; }
public IAsyncValueCommand ExampleValueTaskCommandReturningToTheCallingThread { get; }
public bool IsBusy
{
get => _isBusy;
set
{
if (_isBusy != value)
{
_isBusy = value;
ExampleValueTaskCommandWithCanExecuteChanged.RaiseCanExecuteChanged();
}
}
}
async ValueTask ExampleValueTaskMethod()
{
var random = new Random();
if (random.Next(10) > 9)
await Task.Delay(1000);
}
async ValueTask ExampleValueTaskMethodWithIntParameter(int parameter)
{
var random = new Random();
if (random.Next(10) > 9)
await Task.Delay(parameter);
}
async ValueTask ExampleValueTaskMethodWithException()
{
var random = new Random();
if (random.Next(10) > 9)
await Task.Delay(1000);
throw new Exception();
}
bool CanExecuteInt(int count)
{
if(count > 2)
return true;
return false;
}
void ExecuteCommands()
{
_isBusy = true;
try
{
ExampleValueTaskCommand.Execute(null);
ExampleValueTaskIntCommand.Execute(1000);
ExampleValueTaskExceptionCommand.Execute(null);
ExampleValueTaskCommandReturningToTheCallingThread.Execute(null);
if (ExampleValueTaskCommandWithCanExecuteChanged.CanExecute(null))
ExampleValueTaskCommandWithCanExecuteChanged.Execute(null);
if(ExampleValueTaskIntCommandWithCanExecute.CanExecute(2))
ExampleValueTaskIntCommandWithCanExecute.Execute(2);
}
finally
{
_isBusy = false;
}
}
}
Product | Versions |
---|---|
.NET | net5.0 net5.0-windows net6.0 net6.0-android net6.0-ios net6.0-maccatalyst net6.0-macos net6.0-tvos net6.0-windows net7.0 net7.0-android net7.0-ios net7.0-maccatalyst net7.0-macos net7.0-tvos net7.0-windows |
.NET Core | netcoreapp1.0 netcoreapp1.1 netcoreapp2.0 netcoreapp2.1 netcoreapp2.2 netcoreapp3.0 netcoreapp3.1 |
.NET Standard | netstandard1.0 netstandard1.1 netstandard1.2 netstandard1.3 netstandard1.4 netstandard1.5 netstandard1.6 netstandard2.0 netstandard2.1 |
.NET Framework | net45 net451 net452 net46 net461 net462 net463 net47 net471 net472 net48 net481 |
MonoAndroid | monoandroid |
MonoMac | monomac |
MonoTouch | monotouch |
Tizen | tizen30 tizen40 tizen60 |
Universal Windows Platform | uap uap10.0 |
Windows Phone | wp8 wp81 wpa81 |
Windows Store | netcore netcore45 netcore451 |
Xamarin.iOS | xamarinios |
Xamarin.Mac | xamarinmac |
Xamarin.TVOS | xamarintvos |
Xamarin.WatchOS | xamarinwatchos |
-
.NETStandard 1.0
- AsyncAwaitBestPractices (>= 6.0.6)
-
.NETStandard 2.0
- AsyncAwaitBestPractices (>= 6.0.6)
-
.NETStandard 2.1
- AsyncAwaitBestPractices (>= 6.0.6)
-
net6.0
- AsyncAwaitBestPractices (>= 6.0.6)
-
net7.0
- AsyncAwaitBestPractices (>= 6.0.6)
NuGet packages (6)
Showing the top 5 NuGet packages that depend on AsyncAwaitBestPractices.MVVM:
Package | Downloads |
---|---|
AwaitablePopups
Create your own DisplayAlerts using XAML, or use the DisplayAlerts,LoaderDialogs and LoginViews that's included! Powered by AsyncAwaitBestPractices and Rg.Plugins.Popup |
|
GuardedActions
Package Description |
|
AppHosting.Xamarin.Forms
Provides attributes, controls, extensions methods, Xamarin.Forms page & element middlewares, services & utilities to setup your application infrastructure. Please, head to the project's repository for wiki. |
|
Prism.Kernel
Prism extension framework for adding feature based configuration and Workitem hosting capabilities |
|
Mopups.PreBaked
Transition Package for AwaitablePopups to use Mopups and Maui This package contains pre-built Popups for use in MAUI, see https://github.com/LuckyDucko/AwaitablePopups |
GitHub repositories (7)
Showing the top 5 popular GitHub repositories that depend on AsyncAwaitBestPractices.MVVM:
Repository | Stars |
---|---|
beeradmoore/dlss-swapper
|
|
fernandreu/office-ribbonx-editor
An overhauled fork of the original Custom UI Editor for Microsoft Office, built with WPF
|
|
davidortinau/Xappy
A mobile app to track Xamarin news and explore all the goodness that is .NET for Mobile developers
|
|
xamarin/dev-days-labs
|
|
Goz3rr/SatisfactorySaveEditor
|
Version | Downloads | Last updated |
---|---|---|
6.0.6 | 9,516 | 11/12/2022 |
6.0.5 | 8,718 | 7/3/2022 |
6.0.4 | 48,643 | 11/23/2021 |
6.0.3 | 3,719 | 11/11/2021 |
6.0.2 | 8,735 | 10/12/2021 |
6.0.1 | 7,223 | 9/27/2021 |
6.0.0 | 18,721 | 7/3/2021 |
6.0.0-pre1 | 626 | 6/7/2021 |
5.1.0 | 47,168 | 3/13/2021 |
5.0.2 | 92,903 | 11/2/2020 |
5.0.0-pre2 | 1,409 | 9/17/2020 |
5.0.0-pre1 | 295 | 9/17/2020 |
4.3.0 | 11,181 | 9/15/2020 |
4.3.0-pre1 | 1,415 | 7/29/2020 |
4.2.0 | 19,252 | 7/13/2020 |
4.1.1 | 25,110 | 5/15/2020 |
4.1.1-pre1 | 1,840 | 4/1/2020 |
4.1.0 | 48,651 | 1/30/2020 |
4.1.0-pre2 | 763 | 1/7/2020 |
4.1.0-pre1 | 727 | 12/19/2019 |
4.0.1 | 9,370 | 12/13/2019 |
4.0.0-pre3 | 579 | 11/29/2019 |
4.0.0-pre1 | 355 | 11/7/2019 |
3.1.0 | 17,732 | 8/28/2019 |
3.1.0-pre5 | 601 | 8/20/2019 |
3.1.0-pre4 | 367 | 8/20/2019 |
3.1.0-pre3 | 435 | 8/14/2019 |
3.1.0-pre2 | 528 | 7/31/2019 |
3.1.0-pre1 | 394 | 7/31/2019 |
3.0.0 | 2,358 | 7/30/2019 |
3.0.0-pre4 | 471 | 7/14/2019 |
3.0.0-pre3 | 394 | 7/7/2019 |
3.0.0-pre2 | 450 | 7/2/2019 |
3.0.0-pre1 | 498 | 6/9/2019 |
2.1.1 | 10,888 | 4/17/2019 |
2.1.0 | 3,235 | 1/12/2019 |
2.1.0-pre1 | 782 | 12/27/2018 |
2.0.0 | 727 | 12/19/2018 |
1.2.1 | 633 | 12/17/2018 |
1.1.0 | 633 | 12/16/2018 |
1.0.1 | 660 | 12/15/2018 |
1.0.0 | 866 | 11/30/2018 |
0.9.0 | 845 | 11/22/2018 |
New in this release:
- Add .NET 7.0 Target