Skip to content

Commit e0e50bd

Browse files
Merge pull request #34 from brminnick/Release-v4.1.1
Release v4.1.1
2 parents 4944aa6 + 4edcd69 commit e0e50bd

File tree

12 files changed

+229
-87
lines changed

12 files changed

+229
-87
lines changed

Src/AsyncAwaitBestPractices.MVVM.nuspec

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
33
<metadata minClientVersion="2.5">
44
<id>AsyncAwaitBestPractices.MVVM</id>
5-
<version>4.1.0</version>
5+
<version>4.1.1</version>
66
<title>Async Extensions for ICommand</title>
77
<authors>Brandon Minnick, John Thiriet</authors>
88
<owners>Brandon Minnick</owners>
@@ -24,18 +24,14 @@
2424
</summary>
2525
<tags>task, valuetask, fire and forget, threading, extensions, system.threading.tasks, async, await</tags>
2626
<dependencies>
27-
<dependency id="AsyncAwaitBestPractices" version="4.1.0" />
27+
<dependency id="AsyncAwaitBestPractices" version="4.1.1" />
2828
</dependencies>
2929
<releaseNotes>
3030
New In This Release:
31-
- Unseal AsyncCommand
32-
- Unseal AsyncCommand&lt;T&gt;
33-
- Unseal AsyncValueCommand
34-
- Unseal AsyncValueCommand&lt;T&gt;
35-
- Include Assembly Signing
31+
- Add Extension Methods Without `in` Keyword (provides support for older versions of Visual Studio)
3632
</releaseNotes>
3733
<repository type="git" url="https://github.com/brminnick/AsyncAwaitBestPractices.git" branch="master" commit="8966e2ec7aa3e325256dd4c8acd01073646471de" />
38-
<copyright>Copyright (c) 2018 Brandon Minnick</copyright>
34+
<copyright>Copyright (c) 2020 Brandon Minnick</copyright>
3935
</metadata>
4036
<files>
4137
<file src="AsyncAwaitBestPractices.MVVM\bin\Release\netstandard1.0\AsyncAwaitBestPractices.MVVM.pdb" target="lib\netstandard1.0\AsyncAwaitBestPractices.MVVM.pdb" />

Src/AsyncAwaitBestPractices.MVVM/AsyncCommand.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,12 @@ void ICommand.Execute(object parameter)
6767
switch (parameter)
6868
{
6969
case T validParameter:
70-
ExecuteAsync(validParameter).SafeFireAndForget(_onException, _continueOnCapturedContext);
70+
ExecuteAsync(validParameter).SafeFireAndForget(_onException, in _continueOnCapturedContext);
7171
break;
7272

7373
#pragma warning disable CS8604 // Possible null reference argument.
7474
case null when !typeof(T).GetTypeInfo().IsValueType:
75-
ExecuteAsync((T)parameter).SafeFireAndForget(_onException, _continueOnCapturedContext);
75+
ExecuteAsync((T)parameter).SafeFireAndForget(_onException, in _continueOnCapturedContext);
7676
break;
7777
#pragma warning restore CS8604 // Possible null reference argument.
7878

@@ -141,6 +141,6 @@ public event EventHandler CanExecuteChanged
141141
/// <returns>The executed Task</returns>
142142
public Task ExecuteAsync() => _execute();
143143

144-
void ICommand.Execute(object parameter) => _execute().SafeFireAndForget(_onException, _continueOnCapturedContext);
144+
void ICommand.Execute(object parameter) => _execute().SafeFireAndForget(_onException, in _continueOnCapturedContext);
145145
}
146146
}

Src/AsyncAwaitBestPractices.MVVM/AsyncValueCommand.cs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ public class AsyncValueCommand<T> : IAsyncValueCommand<T>
2424
/// <param name="onException">If an exception is thrown in the Task, <c>onException</c> will execute. If onException is null, the exception will be re-thrown</param>
2525
/// <param name="continueOnCapturedContext">If set to <c>true</c> continue on captured context; this will ensure that the Synchronization Context returns to the calling thread. If set to <c>false</c> continue on a different context; this will allow the Synchronization Context to continue on a different thread</param>
2626
public AsyncValueCommand(Func<T, ValueTask> execute,
27-
Func<object?, bool>? canExecute = null,
28-
Action<Exception>? onException = null,
29-
bool continueOnCapturedContext = false)
27+
Func<object?, bool>? canExecute = null,
28+
Action<Exception>? onException = null,
29+
bool continueOnCapturedContext = false)
3030
{
3131
_execute = execute ?? throw new ArgumentNullException(nameof(execute), $"{nameof(execute)} cannot be null");
3232
_canExecute = canExecute ?? (_ => true);
@@ -67,11 +67,11 @@ void ICommand.Execute(object parameter)
6767
switch (parameter)
6868
{
6969
case T validParameter:
70-
ExecuteAsync(validParameter).SafeFireAndForget(_onException, _continueOnCapturedContext);
70+
ExecuteAsync(validParameter).SafeFireAndForget(_onException, in _continueOnCapturedContext);
7171
break;
7272
#pragma warning disable CS8604 // Possible null reference argument.
7373
case null when !typeof(T).GetTypeInfo().IsValueType:
74-
ExecuteAsync((T)parameter).SafeFireAndForget(_onException, _continueOnCapturedContext);
74+
ExecuteAsync((T)parameter).SafeFireAndForget(_onException, in _continueOnCapturedContext);
7575
break;
7676
#pragma warning restore CS8604 // Possible null reference argument.
7777

@@ -103,9 +103,9 @@ public class AsyncValueCommand : IAsyncValueCommand
103103
/// <param name="onException">If an exception is thrown in the Task, <c>onException</c> will execute. If onException is null, the exception will be re-thrown</param>
104104
/// <param name="continueOnCapturedContext">If set to <c>true</c> continue on captured context; this will ensure that the Synchronization Context returns to the calling thread. If set to <c>false</c> continue on a different context; this will allow the Synchronization Context to continue on a different thread</param>
105105
public AsyncValueCommand(Func<ValueTask> execute,
106-
Func<object?, bool>? canExecute = null,
107-
Action<Exception>? onException = null,
108-
bool continueOnCapturedContext = false)
106+
Func<object?, bool>? canExecute = null,
107+
Action<Exception>? onException = null,
108+
bool continueOnCapturedContext = false)
109109
{
110110
_execute = execute ?? throw new ArgumentNullException(nameof(execute), $"{nameof(execute)} cannot be null");
111111
_canExecute = canExecute ?? (_ => true);
@@ -140,6 +140,6 @@ public event EventHandler CanExecuteChanged
140140
/// <returns>The executed Task</returns>
141141
public ValueTask ExecuteAsync() => _execute();
142142

143-
void ICommand.Execute(object parameter) => _execute().SafeFireAndForget(_onException, _continueOnCapturedContext);
143+
void ICommand.Execute(object parameter) => _execute().SafeFireAndForget(_onException, in _continueOnCapturedContext);
144144
}
145145
}

Src/AsyncAwaitBestPractices.nuspec

Lines changed: 11 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
33
<metadata minClientVersion="2.5">
44
<id>AsyncAwaitBestPractices</id>
5-
<version>4.1.0</version>
5+
<version>4.1.1</version>
66
<title>Task Extensions for System.Threading.Tasks</title>
77
<authors>Brandon Minnick, John Thiriet</authors>
88
<owners>Brandon Minnick</owners>
@@ -25,42 +25,38 @@
2525
<tags>task,fire and forget, threading, extensions, system.threading.tasks,async,await</tags>
2626
<dependencies>
2727
<group targetFramework="netstandard1.0">
28-
<dependency id="System.Threading.Tasks.Extensions" version="4.5.3"/>
28+
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4"/>
2929
</group>
3030
<group targetFramework="netstandard1.1">
31-
<dependency id="System.Threading.Tasks.Extensions" version="4.5.3"/>
31+
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4"/>
3232
</group>
3333
<group targetFramework="netstandard1.2">
34-
<dependency id="System.Threading.Tasks.Extensions" version="4.5.3"/>
34+
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4"/>
3535
</group>
3636
<group targetFramework="netstandard1.3">
37-
<dependency id="System.Threading.Tasks.Extensions" version="4.5.3"/>
37+
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4"/>
3838
</group>
3939
<group targetFramework="netstandard1.4">
40-
<dependency id="System.Threading.Tasks.Extensions" version="4.5.3"/>
40+
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4"/>
4141
</group>
4242
<group targetFramework="netstandard1.5">
43-
<dependency id="System.Threading.Tasks.Extensions" version="4.5.3"/>
43+
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4"/>
4444
</group>
4545
<group targetFramework="netstandard1.6">
46-
<dependency id="System.Threading.Tasks.Extensions" version="4.5.3"/>
46+
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4"/>
4747
</group>
4848
<group targetFramework="netstandard2.0">
49-
<dependency id="System.Threading.Tasks.Extensions" version="4.5.3"/>
49+
<dependency id="System.Threading.Tasks.Extensions" version="4.5.4"/>
5050
</group>
5151
<group targetFramework="netstandard2.1">
5252
</group>
5353
</dependencies>
5454
<releaseNotes>
5555
New In This Release:
56-
- Add SafeFireAndForget(Action&lt;Exception&gt; onException, bool continueOnCapturedContext)
57-
- Add SafeFireAndForget&lt;TException&gt;(Action&lt;Exception&gt; onException, bool continueOnCapturedContext)
58-
- Obsolete: SafeFireAndForget(bool continueOnCapturedContext, Action&lt;Exception&gt; onException)
59-
- Obsolete: SafeFireAndForget&lt;TException&gt;(bool continueOnCapturedContext, Action&lt;TException&gt; onException)
60-
- Include Assembly Signing
56+
- Add Extension Methods Without `in` Keyword (provides support for older versions of Visual Studio)
6157
</releaseNotes>
6258
<repository type="git" url="https://github.com/brminnick/AsyncAwaitBestPractices.git" branch="master" commit="8966e2ec7aa3e325256dd4c8acd01073646471de" />
63-
<copyright>Copyright (c) 2018 Brandon Minnick</copyright>
59+
<copyright>Copyright (c) 2020 Brandon Minnick</copyright>
6460
</metadata>
6561
<files>
6662
<file src="AsyncAwaitBestPractices\bin\Release\netstandard1.0\AsyncAwaitBestPractices.pdb" target="lib\netstandard1.0\AsyncAwaitBestPractices.pdb" />

Src/AsyncAwaitBestPractices/AsyncAwaitBestPractices.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
<DocumentationFile>bin\Release\netstandard1.0\AsyncAwaitBestPractices.xml</DocumentationFile>
1515
</PropertyGroup>
1616
<ItemGroup>
17-
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.3" />
17+
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
1818
</ItemGroup>
1919
<ItemGroup>
2020
<Folder Include="WeakEventManager\" />

Src/AsyncAwaitBestPractices/SafeFireAndForgetExtensions.cs

Lines changed: 1 addition & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ namespace AsyncAwaitBestPractices
66
/// <summary>
77
/// Extension methods for System.Threading.Tasks.Task and System.Threading.Tasks.ValueTask
88
/// </summary>
9-
public static class SafeFireAndForgetExtensions
9+
public static partial class SafeFireAndForgetExtensions
1010
{
1111
static Action<Exception>? _onException;
1212
static bool _shouldAlwaysRethrowException;
@@ -47,48 +47,8 @@ public static class SafeFireAndForgetExtensions
4747
/// <typeparam name="TException">Exception type. If an exception is thrown of a different type, it will not be handled</typeparam>
4848
public static void SafeFireAndForget<TException>(this Task task, in Action<TException>? onException = null, in bool continueOnCapturedContext = false) where TException : Exception => HandleSafeFireAndForget(task, continueOnCapturedContext, onException);
4949

50-
#region Obsolete Methods
51-
/// <summary>
52-
/// Safely execute the ValueTask without waiting for it to complete before moving to the next line of code; commonly known as "Fire And Forget". Inspired by John Thiriet's blog post, "Removing Async Void": https://johnthiriet.com/removing-async-void/.
53-
/// </summary>
54-
/// <param name="task">ValueTask.</param>
55-
/// <param name="continueOnCapturedContext">If set to <c>true</c>, continue on captured context; this will ensure that the Synchronization Context returns to the calling thread. If set to <c>false</c>, continue on a different context; this will allow the Synchronization Context to continue on a different thread</param>
56-
/// <param name="onException">If an exception is thrown in the ValueTask, <c>onException</c> will execute. If onException is null, the exception will be re-thrown</param>
57-
[Obsolete("Use SafeFireAndForget(Action<Exception> onException, bool continueOnCapturedContext)")]
58-
public static void SafeFireAndForget(this ValueTask task, in bool continueOnCapturedContext, in Action<Exception>? onException) => HandleSafeFireAndForget(task, continueOnCapturedContext, onException);
59-
60-
61-
/// <summary>
62-
/// Safely execute the ValueTask without waiting for it to complete before moving to the next line of code; commonly known as "Fire And Forget". Inspired by John Thiriet's blog post, "Removing Async Void": https://johnthiriet.com/removing-async-void/.
63-
/// </summary>
64-
/// <param name="task">ValueTask.</param>
65-
/// <param name="continueOnCapturedContext">If set to <c>true</c>, continue on captured context; this will ensure that the Synchronization Context returns to the calling thread. If set to <c>false</c>, continue on a different context; this will allow the Synchronization Context to continue on a different thread</param>
66-
/// <param name="onException">If an exception is thrown in the Task, <c>onException</c> will execute. If onException is null, the exception will be re-thrown</param>
67-
/// <typeparam name="TException">Exception type. If an exception is thrown of a different type, it will not be handled</typeparam>
68-
[Obsolete("Use SafeFireAndForget<TException>(Action<TException> onException, bool continueOnCapturedContext)")]
69-
public static void SafeFireAndForget<TException>(this ValueTask task, in bool continueOnCapturedContext, in Action<TException>? onException) where TException : Exception => HandleSafeFireAndForget(task, continueOnCapturedContext, onException);
7050

7151

72-
/// <summary>
73-
/// Safely execute the Task without waiting for it to complete before moving to the next line of code; commonly known as "Fire And Forget". Inspired by John Thiriet's blog post, "Removing Async Void": https://johnthiriet.com/removing-async-void/.
74-
/// </summary>
75-
/// <param name="task">Task.</param>
76-
/// <param name="continueOnCapturedContext">If set to <c>true</c>, continue on captured context; this will ensure that the Synchronization Context returns to the calling thread. If set to <c>false</c>, continue on a different context; this will allow the Synchronization Context to continue on a different thread</param>
77-
/// <param name="onException">If an exception is thrown in the Task, <c>onException</c> will execute. If onException is null, the exception will be re-thrown</param>
78-
[Obsolete("Use SafeFireAndForget(Action<Exception> onException, bool continueOnCapturedContext)")]
79-
public static void SafeFireAndForget(this Task task, in bool continueOnCapturedContext, in Action<Exception>? onException) => HandleSafeFireAndForget(task, continueOnCapturedContext, onException);
80-
81-
/// <summary>
82-
/// Safely execute the Task without waiting for it to complete before moving to the next line of code; commonly known as "Fire And Forget". Inspired by John Thiriet's blog post, "Removing Async Void": https://johnthiriet.com/removing-async-void/.
83-
/// </summary>
84-
/// <param name="task">Task.</param>
85-
/// <param name="continueOnCapturedContext">If set to <c>true</c>, continue on captured context; this will ensure that the Synchronization Context returns to the calling thread. If set to <c>false</c>, continue on a different context; this will allow the Synchronization Context to continue on a different thread</param>
86-
/// <param name="onException">If an exception is thrown in the Task, <c>onException</c> will execute. If onException is null, the exception will be re-thrown</param>
87-
/// <typeparam name="TException">Exception type. If an exception is thrown of a different type, it will not be handled</typeparam>
88-
[Obsolete("Use SafeFireAndForget<TException>(Action<TException> onException, bool continueOnCapturedContext)")]
89-
public static void SafeFireAndForget<TException>(this Task task, in bool continueOnCapturedContext, in Action<TException>? onException) where TException : Exception => HandleSafeFireAndForget(task, continueOnCapturedContext, onException);
90-
#endregion
91-
9252
/// <summary>
9353
/// Initialize SafeFireAndForget
9454
///
@@ -114,7 +74,6 @@ public static void SetDefaultExceptionHandling(in Action<Exception> onException)
11474
_onException = onException;
11575
}
11676

117-
#pragma warning disable RECS0165 // Asynchronous methods should return a Task instead of void
11877
static async void HandleSafeFireAndForget<TException>(ValueTask valueTask, bool continueOnCapturedContext, Action<TException>? onException) where TException : Exception
11978
{
12079
try
@@ -144,7 +103,6 @@ static async void HandleSafeFireAndForget<TException>(Task task, bool continueOn
144103
throw;
145104
}
146105
}
147-
#pragma warning restore RECS0165 // Asynchronous methods should return a Task instead of void
148106

149107
static void HandleException<TException>(in TException exception, in Action<TException>? onException) where TException : Exception
150108
{

0 commit comments

Comments
 (0)