Are you creating the tracing delegate in the remote app domain?  You should be 
able to create a class which derives from MarshalByRefObject and then create an 
instance of that object in the remote domain.  You can then call a method on 
that MBRO which does the ScriptEngine.SetTrace() call (you can safely pass the 
script engine instance across when you create the MBRO).  If you want to 
marshal the results back to your main app domain you can also create an MBRO in 
your local domain that you pass through when you construct the remote MBRO and 
then you can call some method which passes strings instead of unmarshallable 
objects.

From: ironpython-users-bounces+dinov=microsoft....@python.org 
[mailto:ironpython-users-bounces+dinov=microsoft....@python.org] On Behalf Of 
Alan Macdonald
Sent: Thursday, January 12, 2012 1:34 AM
To: ironpython-users@python.org
Subject: [Ironpython-users] SerializationException from 
IronPython.Runtime.Types.PythonType

Hello,

I am experiencing an exception when tracing and would appreciate some guidance.

I am hosting IronPython 2.7.1 in a .Net 4 C# host.  The host creates a new app 
domain to run IronPython scripts in.  At the moment due to some security 
exceptions I've given the new app domain unrestricted permissions (I will try 
and reduce this later).  When the python script is executed it runs via an 
asynchronous delegate and when complete catches any exceptions during the 
running of the script.  This was all working fine and if the python script has 
an error in it then the exception is caught in the async callback method.

However I have since added tracing via a call to 
ScriptEngine.SetTrace(myDelegate) so I can allow stepping through the script 
one line at a time (based on http://devhawk.net/tag/debugger/).  When the 
script has no errors it executes fine with tracing enabled or disabled.  
However if the script has an error in it and tracing is enabled then trying to 
catch and format the exception in the async delegate callback causes a 
SerializationException on  IronPython.Runtime.Types.PythonType.  When tracing 
is not enabled the exception is caught and formatted successfully.

I tried to disable tracing in the catch block before formatting the exception 
but this makes no difference.  I understand that this is related to sending the 
exception information from one app domain to another but I'm not sure what I 
can do to get round it and what extra information it is trying to send when 
tracing is enabled.  My tracing delegate does nothing with exceptions.

Code that creates the new app domain and starts the async call to execute the 
method for the object in the new app domain:
public void Run()
        {
            if (newDomainInstance == null)
                NewAppDomain();

            Execute method = newDomainInstance.ExecuteCode;
            method.BeginInvoke(RunComplete, method);

        }


The async callback is the following code:

 private void RunComplete(IAsyncResult cookie)
        {
            Complete = true;

            Execute method = (Execute)cookie.AsyncState;


            try
            {
                method.EndInvoke(cookie);
                OnExecutionSuccess();
            }
            catch (AppDomainUnloadedException adue)
            {
                //Do nothing because we've deliberately pulled the app domain 
out from under it.
            }
            catch (Exception ex)
            {
                engine.Value.SetTrace(null);
                String extractedMessage = 
engine.Value.GetService<ExceptionOperations>().FormatException(ex);
                OnExecutionError(new Exception(extractedMessage));
            }

        }

The exception occurs on String extractedMessage = 
engine.Value.GetService<ExceptionOperations>().FormatException(ex);

Exception stacktrace:
System.Runtime.Serialization.SerializationException was unhandled
  Message=Type 'IronPython.Runtime.Types.PythonType' in Assembly 'IronPython, 
Version=2.7.0.40, Culture=neutral, PublicKeyToken=7f709c5b713576e1' is not 
marked as serializable.
  Source=mscorlib
  StackTrace:
    Server stack trace:
       at 
System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType
 type)
       at 
System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type 
type, StreamingContext context)
       at 
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo()
       at 
System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitSerialize(Object
 obj, ISurrogateSelector surrogateSelector, StreamingContext context, 
SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, 
ObjectWriter objectWriter, SerializationBinder binder)
       at 
System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo
 objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo)
       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.SerializeMessageParts(ArrayList
 argsToSerialize)
       at 
System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage..ctor(IMethodReturnMessage
 mrm)
       at 
System.Runtime.Remoting.Messaging.SmuggledMethodReturnMessage.SmuggleIfPossible(IMessage
 msg)
       at System.Runtime.Remoting.Channels.CrossAppDomainSink.DoDispatch(Byte[] 
reqStmBuff, SmuggledMethodCallMessage smuggledMcm, SmuggledMethodReturnMessage& 
smuggledMrm)
       at 
System.Runtime.Remoting.Channels.CrossAppDomainSink.DoTransitionDispatchCallback(Object[]
 args)
    Exception rethrown at [0]:
       at System.Threading.Thread.InternalCrossContextCallback(Context ctx, 
IntPtr ctxID, Int32 appDomainID, InternalCrossContextDelegate ftnToCall, 
Object[] args)
       at 
System.Runtime.Remoting.Messaging.AsyncReplySink.SyncProcessMessage(IMessage 
reqMsg)
       at 
System.Runtime.Remoting.Channels.ADAsyncWorkItem.FinishAsyncWork(Object 
stateIgnored)
       at 
System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
       at System.Threading.ExecutionContext.Run(ExecutionContext 
executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       at 
System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
       at System.Threading.ThreadPoolWorkQueue.Dispatch()
       at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
  InnerException:


Any help would be appreciated.  If it helps I can show more code or if anything 
is unclear please let me know. I didn't want to make it too long and include 
unneccessary details.

Thanks for your time.

Alan

_______________________________________________
Ironpython-users mailing list
Ironpython-users@python.org
http://mail.python.org/mailman/listinfo/ironpython-users

Reply via email to