I’m interested in creating a windows service process in which each hosted
service is run within its own AppDomain.  The AppDomain and service
creation are working well for me; however, I am not able to use the remote
service object reference as a parameter to the ServiceBase.Run() method.
It appears that this is due to the way Run is attempting to interact with
the service object.  The code I am using and the resulting exception are
displayed below.

Sample Code (just the relevant portion of Main()):

// Determine the name for the current assembly
string currentAssemblyName = Assembly.GetExecutingAssembly().FullName;

// Create the new AppDomain
AppDomain domain = AppDomain.CreateDomain("MyAppDomain");

// Create the service in the AppDomain
object serviceObject = domain.CreateInstanceAndUnwrap
(currentAssemblyName, "MyService");
MyService service = serviceObject as MyService;
if(service != null)
{
    ServiceBase.Run(service);
}

Exception:

System.Runtime.Serialization.SerializationException: The type
System.ServiceProcess.NativeMethods+ENTRY in Assembly
System.ServiceProcess, Version=1.0.5000.0, Culture=neutral,
PublicKeyToken=b03f5f7f11d50a3a is not marked as serializable.

Server stack trace:
   at
System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembe
rs(RuntimeType type, Boolean excludeNonSerializable)
   at System.Runtime.Serialization.FormatterServices.GetSerializableMembers
(Type type, StreamingContext context)
   at
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberIn
fo()
   at
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerializ
e(Object obj, ISurrogateSelector surrogateSelector, StreamingContext
context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter
converter)
   at
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize
(Object obj, ISurrogateSelector surrogateSelector, StreamingContext
context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter
converter)
   at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize
(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean
fCheck)
   at
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize
(Stream serializationStream, Object graph, Header[] headers, Boolean
fCheck)
   at
System.Runtime.Remoting.Channels.CrossAppDomainSerializer.SerializeMessageP
arts(ArrayList argsToSerialize)
   at System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage..ctor
(IMethodReturnMessage mrm)
   at
System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage.SmuggleIfPoss
ible(IMessage msg)
   at System.Runtime.Remoting.Channels.CrossAppDomainSink.DoDispatch(Byte
[] reqStmBuff, SmuggledMethodCallMessage smuggledMcm,
SmuggledMethodReturnMessage& smuggledMrm)
   at
System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatch
(Byte[] reqStmBuff, SmuggledMethodCallMessage smuggledMcm,
SmuggledMethodReturnMessage& smuggledMrm)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage
(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&
msgData, Int32 type)
   at System.ServiceProcess.ServiceBase.Initialize(Boolean
multipleServices)
   at System.ServiceProcess.ServiceBase.Run(ServiceBase[] services)
   at System.ServiceProcess.ServiceBase.Run(ServiceBase service)
   at FCServer.ServerEntryPoint.Main()

I’ve been able to work around this issue by implementing a public Run
method on the service class, which simply calls ServiceBase.Run(this).
Below is an example:

// Method in MyService
public void Run()
{
    ServiceBase.Run(this);
}

// Method invocation in Main()
if(service != null)
{
    service.Run();
}

However, the problem with this pattern is that the call to Run() blocks
Main(), so if I need to create more than one service, this approach will
not work.  I have considered invoking the public Run method on the service
asynchronously and, after all services have been run, blocking on the
return of Run from each service until they complete, but I am wondering if
there is a better or more appropriate way to accomplish this.

Thanks for the help.

Matt

===================================
This list is hosted by DevelopMentor®  http://www.develop.com
Some .NET courses you may be interested in:

NEW! Guerrilla ASP.NET, 17 May 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to