Skip to content

Commit 53392ab

Browse files
committed
Calling AsyncDispose instead of Dispose so we don't call ActionBlock.Completion.Wait()
1 parent 42eee56 commit 53392ab

File tree

9 files changed

+130
-16
lines changed

9 files changed

+130
-16
lines changed

src/netstandard/Default/WampSharp.Fleck/Fleck/FleckWampConnection.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ private void OnConnectionError(Exception exception)
4545
RaiseConnectionError(exception);
4646
}
4747

48-
private void OnConnectionClose()
48+
private async void OnConnectionClose()
4949
{
50-
RaiseConnectionClosed();
50+
await RaiseConnectionClosed().ConfigureAwait(false);
5151
}
5252

5353
protected override void Dispose()

src/netstandard/Extensions/WampSharp.AspNetCore.RawSocket/RawSocketConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ public async Task RunAsync()
9090
mIsConnected = false;
9191
}
9292

93-
RaiseConnectionClosed();
93+
await RaiseConnectionClosed().ConfigureAwait(false);
9494
}
9595

9696
private void ProcessBuffer(in ReadOnlySequence<byte> buffer)

src/netstandard/Extensions/WampSharp.RawSocket/RawSocket/TcpClientConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ await Stream
111111
}
112112
}
113113

114-
RaiseConnectionClosed();
114+
await RaiseConnectionClosed().ConfigureAwait(false);
115115
}
116116
catch (Exception ex)
117117
{

src/netstandard/Extensions/WampSharp.Vtortola/VtortolaWampConnection.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ await mWebsocket.ReadMessageAsync(CancellationToken.None)
4949
}
5050
}
5151

52-
RaiseConnectionClosed();
52+
await RaiseConnectionClosed().ConfigureAwait(false);
5353
}
5454
catch (Exception ex)
5555
{

src/netstandard/Extensions/WampSharp.WebSockets/WebSockets/WebSocketWrapperConnection.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ await this.ClientWebSocket.ConnectAsync(mAddressUri, mCancellationToken)
7676
catch (Exception ex)
7777
{
7878
RaiseConnectionError(ex);
79-
RaiseConnectionClosed();
79+
await RaiseConnectionClosed().ConfigureAwait(false);
8080
}
8181

8282
return false;
@@ -134,7 +134,7 @@ data is very small.
134134
await CloseWebSocket().ConfigureAwait(false);
135135
}
136136

137-
RaiseConnectionClosed();
137+
await RaiseConnectionClosed().ConfigureAwait(false);
138138
}
139139

140140
private async Task CloseWebSocket()

src/netstandard/WampSharp/Core/Listener/Connections/AsyncConnection/AsyncWampConnection.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
namespace WampSharp.Core.Listener
99
{
10-
public abstract class AsyncWampConnection<TMessage> : IWampConnection<TMessage>,
10+
public abstract class AsyncWampConnection<TMessage> : IAsyncWampConnection<TMessage>,
1111
IAsyncDisposable
1212
{
1313
private readonly ActionBlock<WampMessage<object>> mSendBlock;
@@ -56,7 +56,14 @@ protected async Task InnerSend(WampMessage<object> message)
5656

5757
public event EventHandler ConnectionOpen;
5858
public event EventHandler<WampMessageArrivedEventArgs<TMessage>> MessageArrived;
59-
public event EventHandler ConnectionClosed;
59+
public event AsyncEventHandler<EventArgs> ConnectionClosedAsync;
60+
61+
public event EventHandler ConnectionClosed
62+
{
63+
add => ConnectionClosedAsync += value.ConvertToAsync();
64+
remove => ConnectionClosedAsync -= value.ConvertToAsync();
65+
}
66+
6067
public event EventHandler<WampConnectionErrorEventArgs> ConnectionError;
6168
protected abstract Task SendAsync(WampMessage<object> message);
6269

@@ -70,10 +77,10 @@ protected virtual void RaiseMessageArrived(WampMessage<TMessage> message)
7077
MessageArrived?.Invoke(this, new WampMessageArrivedEventArgs<TMessage>(message));
7178
}
7279

73-
protected virtual void RaiseConnectionClosed()
80+
protected virtual async Task RaiseConnectionClosed()
7481
{
7582
mLogger.Debug("Connection has been closed");
76-
ConnectionClosed?.Invoke(this, EventArgs.Empty);
83+
await ConnectionClosedAsync?.InvokeAsync(this, EventArgs.Empty);
7784
}
7885

7986
protected virtual void RaiseConnectionError(Exception ex)

src/netstandard/WampSharp/Core/Listener/Connections/IWampConnection.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,18 @@ public interface IWampConnection<TMessage> : IDisposable
4848
/// </summary>
4949
event EventHandler<WampConnectionErrorEventArgs> ConnectionError;
5050
}
51+
52+
53+
/// <summary>
54+
/// A <see cref="IWampConnection{TMessage}"/> with async features
55+
/// </summary>
56+
/// <typeparam name="TMessage"></typeparam>
57+
internal interface IAsyncWampConnection<TMessage> : IWampConnection<TMessage>,
58+
IAsyncDisposable
59+
{
60+
/// <summary>
61+
/// Occurs when this connection closes.
62+
/// </summary>
63+
event AsyncEventHandler<EventArgs> ConnectionClosedAsync;
64+
}
5165
}

src/netstandard/WampSharp/Core/Listener/Connections/ReviveClientConnection.cs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Threading.Tasks;
23
using WampSharp.Core.Message;
34

45
namespace WampSharp.Core.Listener
@@ -28,13 +29,28 @@ private IControlledWampConnection<TMessage> SetupConnection()
2829
IControlledWampConnection<TMessage> result = mFactory();
2930

3031
result.ConnectionOpen += OnConnectionOpen;
31-
result.ConnectionClosed += OnConnectionClosed;
3232
result.ConnectionError += OnConnectionError;
3333
result.MessageArrived += OnMessageArrived;
3434

35+
if (result is IAsyncWampConnection<TMessage> asyncWampConnection)
36+
{
37+
asyncWampConnection.ConnectionClosedAsync += OnConnectionClosedAsync;
38+
}
39+
else
40+
{
41+
result.ConnectionClosed += OnConnectionClosed;
42+
}
43+
3544
return result;
3645
}
3746

47+
private async Task OnConnectionClosedAsync(object sender, EventArgs e)
48+
{
49+
await DestroyConnectionAsync().ConfigureAwait(false);
50+
51+
RaiseConnectionClosed();
52+
}
53+
3854
private void OnMessageArrived(object sender, WampMessageArrivedEventArgs<TMessage> e)
3955
{
4056
RaiseMessageArrived(e);
@@ -52,17 +68,33 @@ private void OnConnectionClosed(object sender, EventArgs e)
5268
RaiseConnectionClosed();
5369
}
5470

71+
private async Task DestroyConnectionAsync()
72+
{
73+
UnwireEvents();
74+
IAsyncWampConnection<TMessage> connection = mConnection as IAsyncWampConnection<TMessage>;
75+
76+
connection.ConnectionClosedAsync -= OnConnectionClosedAsync;
77+
await connection.DisposeAsync().ConfigureAwait(false);
78+
79+
mConnection = null;
80+
}
81+
5582
private void DestroyConnection()
5683
{
57-
mConnection.ConnectionOpen -= OnConnectionOpen;
58-
mConnection.ConnectionClosed -= OnConnectionClosed;
59-
mConnection.ConnectionError -= OnConnectionError;
60-
mConnection.MessageArrived -= OnMessageArrived;
84+
UnwireEvents();
6185

6286
mConnection.Dispose();
6387
mConnection = null;
6488
}
6589

90+
private void UnwireEvents()
91+
{
92+
mConnection.ConnectionOpen -= OnConnectionOpen;
93+
mConnection.ConnectionError -= OnConnectionError;
94+
mConnection.MessageArrived -= OnMessageArrived;
95+
mConnection.ConnectionClosed -= OnConnectionClosed;
96+
}
97+
6698
private void OnConnectionOpen(object sender, EventArgs e)
6799
{
68100
RaiseConnectionOpen();
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.Immutable;
4+
using System.Linq;
5+
using System.Threading.Tasks;
6+
7+
namespace WampSharp.Core
8+
{
9+
public delegate Task AsyncEventHandler<in TEventArgs>(object sender, TEventArgs e) where TEventArgs : EventArgs;
10+
11+
public static class AsyncEventHandlerExtensions
12+
{
13+
public static async Task InvokeAsync<TEventArgs>(this AsyncEventHandler<TEventArgs> handler, object sender,
14+
TEventArgs e) where TEventArgs : EventArgs
15+
{
16+
if (handler == null)
17+
{
18+
throw new ArgumentNullException(nameof(handler));
19+
}
20+
21+
Delegate[] invocationList = handler.GetInvocationList();
22+
23+
foreach (AsyncEventHandler<TEventArgs> currentSubscriber in invocationList
24+
.Cast<AsyncEventHandler<TEventArgs>>())
25+
{
26+
await currentSubscriber(sender, e).ConfigureAwait(false);
27+
}
28+
}
29+
30+
public static AsyncEventHandler<EventArgs> ConvertToAsync
31+
(this EventHandler handler)
32+
{
33+
if (handler == null)
34+
{
35+
throw new ArgumentNullException(nameof(handler));
36+
}
37+
38+
return (sender, args) =>
39+
{
40+
handler(sender, args);
41+
return Task.CompletedTask;
42+
};
43+
}
44+
45+
46+
public static AsyncEventHandler<TEventArgs> ConvertToAsync<TEventArgs>
47+
(this EventHandler<TEventArgs> handler) where TEventArgs : EventArgs
48+
{
49+
if (handler == null)
50+
{
51+
throw new ArgumentNullException(nameof(handler));
52+
}
53+
54+
return (sender, args) =>
55+
{
56+
handler(sender, args);
57+
return Task.CompletedTask;
58+
};
59+
}
60+
}
61+
}

0 commit comments

Comments
 (0)