Hopefully the .NET 2.0 bits will support a similar call to reset the remoting infrastructure the clear way without restarting the whole remoting application!
As you may have noticed: there exists a RemotingChannels.UnregisterChannel() method to use to get rid of a old used channel and switch to a new one (registering). But that is not enough to get an application seamlessly work with a new remoting service endpoint: after you really used one of you configured services, you will get an exception if you try to register the service again with a different service endpoint. This is because the RemotingConfigHandler+RemotingConfigInfo method AddWellknownEntry() calls a method named CheckForRedirectedClientType() that cause a CantUseRedirectedTypeForWellKnownService exception. So after I tried a "fix" with managing the calls to the .NET remoting classes within a new separate AppDomain (and unload that on a reset remoting request) that did not work I end up with a hack using Reflection to get around that.
Here is the used code that works for our requirements:
/// <summary>
/// This is cool, but it is a HACK. Please validate the code each time
/// the .NET framework gets updated. There is a little safty included to
/// throw a InvalidOperationException if something changed we require to get
/// it work somehow.
/// </summary>
/// <exception cref="InvalidOperationException">
/// On every failed reflection call or if we do not get any of
/// the required FieldInfo objects</exception>
/// <remarks>
/// The HACK bases on the fact Remoting informations are cached
/// in the well hidden sync. Hashtable field "_remoteTypeInfo" after they get used once.
/// This field you can find within the (internal) class
/// RemotingConfigHandler.RemotingConfigInfo. The static RemotingConfigHandler.Info
/// field holds a reference to an instance if that class.
/// To reset we simply initialize that field with a new instance of
/// a synchronized Hashtable.
/// Note: We do only "fix" for Singleton objects, not client activated services.
/// So to get it "fully" work (complete state reset), you may have to hack
/// more and other fields.
/// </remarks>
private static void Release_NETRemotingResources() {
bool raiseError = true; // warn if we switch to a new .NET env where the reflection is maybe not working anymore!
try {
//HACK: please verify it after each Service Pack or new version of .NET runtime to be used!
Type configHandlerType = Type.GetType("System.Runtime.Remoting.RemotingConfigHandler");
if (configHandlerType != null) {
FieldInfo infoFI = configHandlerType.GetField("Info", BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);
if (infoFI != null) {
object infoFIRef = infoFI.GetValue(null); // static, so no object instance to provide
if (infoFIRef != null) {
FieldInfo remoteTypeInfoFI = infoFI.FieldType.GetField("_remoteTypeInfo", BindingFlags.Instance | BindingFlags.NonPublic);
if (remoteTypeInfoFI != null) {
remoteTypeInfoFI.SetValue(infoFIRef, Hashtable.Synchronized(new Hashtable()));
raiseError = false; // all seems to be OK
}
} catch (Exception ex) {
throw new InvalidOperationException("Failed to reset .NET internal remoting state.", ex);
if (raiseError)
throw new InvalidOperationException("Failed to reset .NET internal remoting state.");
© Copyright 2002-2008, Torsten Rendelmann Page rendered at Wednesday, November 19, 2008 4:43:02 PM (W. Europe Standard Time, UTC+01:00)
Like RSS Bandit? Make a donation to help support its development and maintenance. As little as 1€ will help.
SUBSCRIBE RSS GeoURL
newtelligence dasBlog 2.1.8102.813
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.