e79aa3c0ed
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
158 lines
5.3 KiB
C#
158 lines
5.3 KiB
C#
//----------------------------------------------------------------
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
//----------------------------------------------------------------
|
|
|
|
namespace System.ServiceModel.Routing
|
|
{
|
|
using System;
|
|
using System.Diagnostics.CodeAnalysis;
|
|
using System.Collections.Generic;
|
|
using System.Runtime;
|
|
using System.ServiceModel.Description;
|
|
using System.ServiceModel.Channels;
|
|
using System.ComponentModel;
|
|
using System.Threading;
|
|
|
|
class SessionChannels
|
|
{
|
|
Guid activityID;
|
|
[Fx.Tag.SynchronizationObject]
|
|
Dictionary<RoutingEndpointTrait, IRoutingClient> sessions;
|
|
List<IRoutingClient> sessionList;
|
|
|
|
[SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode, Justification = "gets called in RoutingService.ctor()")]
|
|
public SessionChannels(Guid activityID)
|
|
{
|
|
this.activityID = activityID;
|
|
this.sessions = new Dictionary<RoutingEndpointTrait, IRoutingClient>();
|
|
this.sessionList = new List<IRoutingClient>();
|
|
}
|
|
|
|
void ChannelFaulted(object sender, EventArgs args)
|
|
{
|
|
FxTrace.Trace.SetAndTraceTransfer(this.activityID, true);
|
|
IRoutingClient client = (IRoutingClient)sender;
|
|
if (TD.RoutingServiceChannelFaultedIsEnabled())
|
|
{
|
|
TD.RoutingServiceChannelFaulted(client.Key.ToString());
|
|
}
|
|
this.AbortChannel(client.Key);
|
|
}
|
|
|
|
[SuppressMessage(FxCop.Category.Performance, FxCop.Rule.AvoidUncalledPrivateCode, Justification = "BeginClose is called by RoutingChannelExtension.AttachService")]
|
|
public IAsyncResult BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
|
|
{
|
|
List<ICommunicationObject> localClients = null;
|
|
|
|
lock (this.sessions)
|
|
{
|
|
if (this.sessions.Count > 0)
|
|
{
|
|
localClients = this.sessionList.ConvertAll<ICommunicationObject>((client) => (ICommunicationObject)client);
|
|
this.sessionList.Clear();
|
|
this.sessions.Clear();
|
|
}
|
|
}
|
|
|
|
if (localClients != null && localClients.Count > 0)
|
|
{
|
|
localClients.ForEach((client) =>
|
|
{
|
|
if (TD.RoutingServiceClosingClientIsEnabled())
|
|
{
|
|
TD.RoutingServiceClosingClient(((IRoutingClient)client).Key.ToString());
|
|
}
|
|
});
|
|
return new CloseCollectionAsyncResult(timeout, callback, state, localClients);
|
|
}
|
|
else
|
|
{
|
|
return new CompletedAsyncResult(callback, state);
|
|
}
|
|
}
|
|
|
|
public void EndClose(IAsyncResult asyncResult)
|
|
{
|
|
if (asyncResult is CloseCollectionAsyncResult)
|
|
{
|
|
CloseCollectionAsyncResult.End(asyncResult);
|
|
}
|
|
else
|
|
{
|
|
CompletedAsyncResult.End(asyncResult);
|
|
}
|
|
}
|
|
|
|
internal IRoutingClient GetOrCreateClient<TContract>(RoutingEndpointTrait key, RoutingService service, bool impersonating)
|
|
{
|
|
IRoutingClient value;
|
|
lock (this.sessions)
|
|
{
|
|
if (!this.sessions.TryGetValue(key, out value))
|
|
{
|
|
//Create the client here
|
|
value = ClientFactory.Create(key, service, impersonating);
|
|
value.Faulted += ChannelFaulted;
|
|
this.sessions[key] = value;
|
|
sessionList.Add(value);
|
|
}
|
|
}
|
|
return value;
|
|
}
|
|
|
|
public void AbortAll()
|
|
{
|
|
List<IRoutingClient> clients = new List<IRoutingClient>();
|
|
|
|
lock (this.sessions)
|
|
{
|
|
foreach (IRoutingClient client in this.sessions.Values)
|
|
{
|
|
clients.Add(client);
|
|
}
|
|
this.sessions.Clear();
|
|
this.sessionList.Clear();
|
|
}
|
|
|
|
foreach (IRoutingClient client in clients)
|
|
{
|
|
RoutingUtilities.Abort((ICommunicationObject)client, client.Key);
|
|
}
|
|
}
|
|
|
|
public void AbortChannel(RoutingEndpointTrait key)
|
|
{
|
|
IRoutingClient client;
|
|
lock (this.sessions)
|
|
{
|
|
if (this.sessions.TryGetValue(key, out client))
|
|
{
|
|
this.sessions.Remove(key);
|
|
this.sessionList.Remove(client);
|
|
}
|
|
}
|
|
|
|
if (client != null)
|
|
{
|
|
RoutingUtilities.Abort((ICommunicationObject)client, client.Key);
|
|
}
|
|
}
|
|
|
|
public IRoutingClient ReleaseChannel()
|
|
{
|
|
IRoutingClient client = null;
|
|
lock (this.sessions)
|
|
{
|
|
int count = this.sessionList.Count;
|
|
if (count > 0)
|
|
{
|
|
client = this.sessionList[count - 1];
|
|
this.sessionList.RemoveAt(count - 1);
|
|
this.sessions.Remove(client.Key);
|
|
}
|
|
}
|
|
return client;
|
|
}
|
|
}
|
|
}
|