1
0
mirror of https://github.com/JKorf/CryptoExchange.Net synced 2025-06-11 18:06:27 +00:00

added lock for events, fixed some forgotten configureawait(false) calls

This commit is contained in:
Jan Korf 2018-12-28 21:44:38 +01:00
parent 36169d08a3
commit b423d4b6c7
2 changed files with 50 additions and 29 deletions

View File

@ -26,6 +26,7 @@ namespace CryptoExchange.Net.Sockets
private bool lostTriggered; private bool lostTriggered;
private readonly List<SocketEvent> waitingForEvents; private readonly List<SocketEvent> waitingForEvents;
private object eventLock = new object();
public SocketSubscription(IWebsocket socket) public SocketSubscription(IWebsocket socket)
@ -44,8 +45,11 @@ namespace CryptoExchange.Net.Sockets
Socket.DisconnectTime = DateTime.UtcNow; Socket.DisconnectTime = DateTime.UtcNow;
lostTriggered = true; lostTriggered = true;
foreach (var events in Events) lock (eventLock)
events.Reset(); {
foreach (var events in Events)
events.Reset();
}
if (Socket.ShouldReconnect) if (Socket.ShouldReconnect)
ConnectionLost?.Invoke(); ConnectionLost?.Invoke();
@ -62,72 +66,89 @@ namespace CryptoExchange.Net.Sockets
public void AddEvent(string name) public void AddEvent(string name)
{ {
Events.Add(new SocketEvent(name)); lock (eventLock)
Events.Add(new SocketEvent(name));
} }
public void SetEventByName(string name, bool success, Error error) public void SetEventByName(string name, bool success, Error error)
{ {
var waitingEvent = waitingForEvents.SingleOrDefault(e => e.Name == name); lock (eventLock)
if (waitingEvent != null)
{ {
waitingEvent.Set(success, error); var waitingEvent = waitingForEvents.SingleOrDefault(e => e.Name == name);
waitingForEvents.Remove(waitingEvent); if (waitingEvent != null)
{
waitingEvent.Set(success, error);
waitingForEvents.Remove(waitingEvent);
}
} }
} }
public void SetEventById(string id, bool success, Error error) public void SetEventById(string id, bool success, Error error)
{ {
var waitingEvent = waitingForEvents.SingleOrDefault(e => e.WaitingId == id); lock (eventLock)
if (waitingEvent != null)
{ {
waitingEvent.Set(success, error); var waitingEvent = waitingForEvents.SingleOrDefault(e => e.WaitingId == id);
waitingForEvents.Remove(waitingEvent); if (waitingEvent != null)
{
waitingEvent.Set(success, error);
waitingForEvents.Remove(waitingEvent);
}
} }
} }
public SocketEvent GetWaitingEvent(string name) public SocketEvent GetWaitingEvent(string name)
{ {
return waitingForEvents.SingleOrDefault(w => w.Name == name); lock (eventLock)
return waitingForEvents.SingleOrDefault(w => w.Name == name);
} }
public Task<CallResult<bool>> WaitForEvent(string name, TimeSpan timeout) public Task<CallResult<bool>> WaitForEvent(string name, TimeSpan timeout)
{ {
return WaitForEvent(name, (int)Math.Round(timeout.TotalMilliseconds, 0)); lock (eventLock)
return WaitForEvent(name, (int)Math.Round(timeout.TotalMilliseconds, 0));
} }
public Task<CallResult<bool>> WaitForEvent(string name, int timeout) public Task<CallResult<bool>> WaitForEvent(string name, int timeout)
{ {
var evnt = Events.Single(e => e.Name == name); lock (eventLock)
waitingForEvents.Add(evnt); {
return Task.Run(() => evnt.Wait(timeout)); var evnt = Events.Single(e => e.Name == name);
waitingForEvents.Add(evnt);
return Task.Run(() => evnt.Wait(timeout));
}
} }
public Task<CallResult<bool>> WaitForEvent(string name, string id, TimeSpan timeout) public Task<CallResult<bool>> WaitForEvent(string name, string id, TimeSpan timeout)
{ {
return WaitForEvent(name, id, (int)Math.Round(timeout.TotalMilliseconds, 0)); lock (eventLock)
return WaitForEvent(name, id, (int)Math.Round(timeout.TotalMilliseconds, 0));
} }
public Task<CallResult<bool>> WaitForEvent(string name, string id, int timeout) public Task<CallResult<bool>> WaitForEvent(string name, string id, int timeout)
{ {
var evnt = Events.Single(e => e.Name == name); lock (eventLock)
evnt.WaitingId = id; {
waitingForEvents.Add(evnt); var evnt = Events.Single(e => e.Name == name);
return Task.Run(() => evnt.Wait(timeout)); evnt.WaitingId = id;
waitingForEvents.Add(evnt);
return Task.Run(() => evnt.Wait(timeout));
}
} }
public void ResetEvents() public void ResetEvents()
{ {
foreach (var waiting in new List<SocketEvent>(waitingForEvents)) lock (eventLock)
waiting.Set(false, new UnknownError("Connection reset")); {
waitingForEvents.Clear(); foreach (var waiting in waitingForEvents)
waiting.Set(false, new UnknownError("Connection reset"));
waitingForEvents.Clear();
}
} }
public async Task Close() public async Task Close()
{ {
Socket.ShouldReconnect = false; Socket.ShouldReconnect = false;
await Socket.Close(); await Socket.Close().ConfigureAwait(false);
Socket.Dispose(); Socket.Dispose();
} }
} }

View File

@ -41,7 +41,7 @@ namespace CryptoExchange.Net.Sockets
/// <returns></returns> /// <returns></returns>
public async Task Close() public async Task Close()
{ {
await subscription.Close(); await subscription.Close().ConfigureAwait(false);
} }
} }
} }