void StopConnection() { if (isStopping) { return; } Guid[] allRemoteClients; lock (startingLock) { if (updatingRedis == null) { return; } if (isStopping) { return; } isStopping = true; RemoveAllClients(); updatingRedisCancellation.Cancel(); updatingRedis.Wait(); updatingRedis = null; updatingRedisCancellation.Dispose(); updatingRedisCancellation = null; updatingRedisWaitingCancellation.Dispose(); updatingRedisWaitingCancellation = null; subscriber.UnsubscribeAll(); redisConnection.Close(); redisConnection.Dispose(); redisDatabase = null; redisConnection = null; allRemoteClients = GetAllRemoteClients().ToArray(); foreach (var remoteClientId in allRemoteClients) { clientTable.Remove(remoteClientId); } clientTable = new ClientTable(privateChannelNamePrefix); clients = new ConcurrentDictionary <Guid, ClientEntity>(); targets = new ConcurrentDictionary <RedisChannel, Guid>(); AdapterStopped?.Invoke(this, EventArgs.Empty); } if (RemoteClientRemoved != null) { foreach (var remoteClientId in allRemoteClients) { RemoteClientRemoved(this, new ClientIdEventArgs(remoteClientId)); } } }
void FromAdapter_RemoveClient(Guid[] clientId) { foreach (var client in clientId) { if (client != this.clientId && clientTable.Remove(client) && isStarted) { RemoteClientRemoved?.Invoke(this, new ClientIdEventArgs(client)); } } }
void StopProcessing(bool fromReadingJob) { if (isStopping) { return; } Guid[] allRemoteClients; lock (startingLock) //only for starting lock { if (readingJob == null) { return; } if (isStopping) { return; } isStopping = true; if (sendingNormal) { sendingBuffers.Add(new byte[] { 255 }); //Link closed. sendingBuffers.CompleteAdding(); while (!sendingBuffers.IsCompleted && sendingNormal) { Task.Delay(100).Wait(); } } shuttingdownTokenSource.Cancel(); inputStream.Close(); //Need to close 1st to make readingJob closable. if (!fromReadingJob) { readingJob.Wait(); } writingJob.Wait(); keepingJob.Wait(); outputStream.Close(); allRemoteClients = GetAllRemoteClients().ToArray(); foreach (var remoteClientId in allRemoteClients) { clientTable.Remove(remoteClientId); } readingJob = null; writingJob = null; keepingJob = null; inputStream = null; outputStream = null; sendingBuffers = null; shuttingdownTokenSource.Dispose(); //OnAdapterStopped will be raised at the end of receiving procedure. } if (RemoteClientRemoved != null) { foreach (var remoteClientId in allRemoteClients) { RemoteClientRemoved(this, new ClientIdEventArgs(remoteClientId)); } } }