public void Dispose()
{
knownChains = new ConcurrentBag<WorkerChain>(knownChains.Where(row => row != this));
if (IsDisposed || IsDisposing)
return;
IsDisposing = true;
if (workers[0] is TcpReceiver)
{
if (Side == ChainSide.SERVER_CONN)
TcpManager.DropServerConnection(this);
else
{
try
{
IPEndPoint addr = ((TcpReceiver)workers[0]).RemoteEndPoint;
TcpManager.DropClientConnection(addr);
}
catch
{
}
}
}
foreach (var i in workers)
i.Dispose();
//((IDisposable)workers[0]).Dispose();
//List<DataPacket> packets = new List<DataPacket>();
/*lock (lockChainManagement)
{*/
// Unsubscribe all monitors used by a given client (used only by client chains)
foreach (var monitor in Subscriptions)
{
Handlers.EventAdd.Unsubscribe(monitor.Value);
}
//}
// Remove channel subscriptions
foreach (var i in ChannelSubscriptions)
{
Record r = InfoService.SubscribedChannel[i.Key];
if (r == null)
continue;
foreach (var j in r.SubscriptionList)
{
InfoService.ChannelSubscription.Remove(j);
CidGenerator.ReleaseCid(j);
}
Debug.Assert(r.GWCID != null, "r.GWCID != null");
InfoService.ChannelSubscription.Remove(r.GWCID.Value);
CidGenerator.ReleaseCid(r.GWCID.Value);
InfoService.SubscribedChannel.Remove(i.Key);
}
// Remove all channels linked to this chain (used only by IOC chains)
foreach (string channel in Channels)
{
//InfoService.SearchChannelEndPoint.Remove(channel);
if (Log.WillDisplay(System.Diagnostics.TraceEventType.Verbose))
Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, ChainId, "Dropping channel " + channel);
List<WorkerChain> channelsToDrop;
/*lock (lockChainManagement)
{
channelsToDrop = knownChains
.Where(row => row.Side != ChainSide.SERVER_CONN && row.ChannelCid.ContainsKey(channel)).ToList();
}*/
channelsToDrop = knownChains
.Where(row => row.Side != ChainSide.SERVER_CONN && row.ChannelCid.ContainsKey(channel)).ToList();
// Disonnect all clients which use a channel
foreach (WorkerChain chain in channelsToDrop)
chain.Dispose();
/*// Send CA_PROTO_SERVER_DISCONN to all clients which use a channel
foreach (WorkerChain chain in channelsToDrop)
{
DataPacket newPacket = DataPacket.Create(0, this);
newPacket.Command = 27;
newPacket.Parameter1 = chain.ChannelCid[channel];
newPacket.Destination = chain.ClientEndPoint;
TcpManager.SendClientPacket(newPacket);
InfoService.ChannelCid.Remove(chain.ChannelCid[channel]);
CidGenerator.ReleaseCid(chain.ChannelCid[channel]);
}*/
try
{
Record record = InfoService.ChannelEndPoint[channel];
if (record != null && record.GWCID != null)
{
InfoService.ChannelCid.Remove(record.GWCID.Value);
CidGenerator.ReleaseCid(record.GWCID.Value);
}
InfoService.ChannelEndPoint.Remove(channel);
}
catch
{
}
if (Log.WillDisplay(System.Diagnostics.TraceEventType.Verbose))
Log.TraceEvent(System.Diagnostics.TraceEventType.Verbose, ChainId, "NB known channels: " + InfoService.ChannelEndPoint.Count);
}
/*lock (lockChainManagement)
{
// Remove the chain from the known chains
knownChains.Remove(this);
}*/
//knownChains = new ConcurrentBag<WorkerChain>(knownChains.Where(row => row != this));
// Remove the chain from the other chains
WorkerChain outValue;
foreach (WorkerChain chain in knownChains)
chain.usedBy.TryRemove(this, out outValue);
// Mark all chains which may need to be disconnected
foreach (var i in knownChains.Where(row => row.Side == ChainSide.SERVER_CONN
&& row.usedBy.Count == 0 && row.lastNonUsed == null))
i.lastNonUsed = Gateway.Now;
/*IEnumerable<WorkerChain> markAsUnUsed;
lock (lockChainManagement)
{
markAsUnUsed = knownChains
.Where(row => row.Side == ChainSide.SERVER_CONN
&& row.usedBy.Count == 0 && row.lastNonUsed == null).ToList();
}
foreach (WorkerChain chain in markAsUnUsed)
chain.lastNonUsed = Gateway.Now;*/
IsDisposed = true;
}