Skip to content

Commit fde90b0

Browse files
David FallahDavid Fallah
David Fallah
authored and
David Fallah
committed
Merge branch 'release/0.2.1'
2 parents 67636d1 + fbcab82 commit fde90b0

File tree

6 files changed

+45
-12
lines changed

6 files changed

+45
-12
lines changed

GitVersion.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
next-version: 0.2.0
1+
next-version: 0.2.1
22
branches:
33
master:
44
increment: None

README.md

+19
Original file line numberDiff line numberDiff line change
@@ -62,4 +62,23 @@ public class TemperatureRecorder
6262
}
6363
```
6464

65+
#### Interop with synchronous event handlers
66+
67+
AsyncEvent is meant to allow the specification of events that may need to be handled asynchronously. However, there's potentially a lot of cases where this handling can be purely synchronous, such as if clients simply want to log the event.
68+
69+
AsyncEvent exposes utility functions that allow synchronous event handlers to be adapted for use with asynchronous events. To make use of these, add `using static AsyncEvent.Extensions` in the source code, then wrap synchronous event handlers in `Async(...)` or `Async<TEventArgs>(...)`. For example:
70+
71+
```cs
72+
using static AsyncEvent.Extensions;
73+
74+
// ...
75+
76+
thermometer.TemperatureChanged += Async<TemperatureChangedEventArgs>(
77+
(s, e) => Console.WriteLine($"New temperature: {e.Celcius}°C"));
78+
```
79+
80+
The adapted event handler will perform the same logic as the synchronous event handler and return a completed task.
81+
82+
#### Examples
83+
6584
Check under `examples/` for complete and runnable example projects.

appveyor.yml

+3-2
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,13 @@ branches:
55
- develop
66
install:
77
- cinst gitversion.portable -y
8+
- ps: dotnet tool install --global dotnet-setversion
89
before_build:
910
- nuget restore
1011
- ps: $env:VERSION=$(gitversion /showvariable NuGetVersionV2)
1112
build_script:
1213
- ps: dotnet restore
13-
- ps: cd src/AsyncEvent; dotnet setversion $env:VERSION; cd ../..
14+
- ps: cd src/AsyncEvent; setversion $env:VERSION; cd ../..
1415
- ps: dotnet build
1516
- ps: dotnet pack --include-source --include-symbols -c Release -o out/
1617
test_script:
@@ -22,7 +23,7 @@ deploy:
2223
provider: NuGet
2324
skip_symbols: false
2425
api_key:
25-
secure: USCwZe1eILJaDmG30VFhlFWmr2P0G6o0HhUau72/W+TzyAMZyqEfL//vQhfjTSKP
26+
secure: u6wyCWr7El0iC167KlsklNSFw5xXBq3WPgegevdthWJfGRHQlCrcxc7AikJh+ePS
2627
artifact: NuGet packages
2728
on:
2829
branch: master

src/AsyncEvent/AsyncEvent.csproj

-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,4 @@
1111
<RepositoryType>git</RepositoryType>
1212
<RepositoryUrl>https://github.com/TAGC/AsyncEvent</RepositoryUrl>
1313
</PropertyGroup>
14-
<ItemGroup>
15-
<DotNetCliToolReference Include="dotnet-setversion" Version="*" />
16-
</ItemGroup>
1714
</Project>

src/AsyncEvent/AsyncEventHandler.cs

+12-4
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ public static AsyncEventHandler<TEventArgs> Async<TEventArgs>(EventHandler<TEven
6666
/// <param name="sender">The object firing the event.</param>
6767
/// <param name="eventArgs">The object containing the event data.</param>
6868
/// <returns>
69-
/// A task that completes only when all registered handlers complete. A completed task is returned if the event handler is
70-
/// null.
69+
/// A <see cref="Task"/> that completes only when all registered handlers complete. A completed task is returned
70+
/// if the event handler is <c>null</c>.
7171
/// </returns>
7272
public static Task InvokeAsync(this AsyncEventHandler eventHandler, object sender, EventArgs eventArgs)
7373
{
@@ -89,16 +89,24 @@ public static Task InvokeAsync(this AsyncEventHandler eventHandler, object sende
8989
/// <param name="eventHandler">This event handler.</param>
9090
/// <param name="sender">The object firing the event.</param>
9191
/// <param name="eventArgs">The object containing the event data.</param>
92-
/// <returns>A task that completes only when all registered handlers complete.</returns>
92+
/// <returns>
93+
/// A <see cref="Task"/> that completes only when all registered handlers complete. A completed task is returned
94+
/// if the event handler is <c>null</c>.
95+
/// </returns>
9396
public static Task InvokeAsync<TEventArgs>(
9497
this AsyncEventHandler<TEventArgs> eventHandler,
9598
object sender,
9699
TEventArgs eventArgs)
97100
{
101+
if (eventHandler == null)
102+
{
103+
return Task.CompletedTask;
104+
}
105+
98106
var delegates = eventHandler.GetInvocationList().Cast<AsyncEventHandler<TEventArgs>>();
99107
var tasks = delegates.Select(it => it.Invoke(sender, eventArgs));
100108

101109
return Task.WhenAll(tasks);
102110
}
103111
}
104-
}
112+
}

test/AsyncEvent.Tests/AsyncEventSpec.cs

+10-2
Original file line numberDiff line numberDiff line change
@@ -82,13 +82,21 @@ async Task RespondToSomethingHappening(object sender, ExampleEventArgs eventArgs
8282
}
8383

8484
[Fact]
85-
internal void Invoke_Async_Should_Return_Completed_Task_If_No_Handlers_Are_Subscribed()
85+
internal void Non_Generic_Invoke_Async_Should_Return_Completed_Task_If_No_Handlers_Are_Subscribed()
8686
{
8787
var notifier = new NonGenericNotifier();
8888

8989
notifier.OnSomethingHappening().IsCompleted.ShouldBeTrue();
9090
}
9191

92+
[Fact]
93+
internal void Generic_Invoke_Async_Should_Return_Completed_Task_If_No_Handlers_Are_Subscribed()
94+
{
95+
var notifier = new GenericNotifier();
96+
97+
notifier.OnSomethingHappening(3).IsCompleted.ShouldBeTrue();
98+
}
99+
92100
[Fact]
93101
internal async Task Non_Generic_Async_Event_Should_Run_Asynchronously()
94102
{
@@ -158,4 +166,4 @@ private class NonGenericNotifier
158166
public Task OnSomethingHappening() => SomethingHappened.InvokeAsync(this, EventArgs.Empty);
159167
}
160168
}
161-
}
169+
}

0 commit comments

Comments
 (0)