12

When marshaling objects between AppDomains in .NET the CLR will either serialize the object (if it has the Serializable attribute) or it will generate a proxy (if it inherits from MarshalByRef)

With strings however the CLR will just pass the reference to the string object into the new AppDomain. The CLR still ensures integrity since .NET strings are immutable and any change by the second AppDomain to the string will not effect the original object.

Which brings me to my question: is there a way to tell the CLR that my custom type is immutable and when used in remoting it should just pass the reference to the object as it does with the string class?

Yona
  • 9,392
  • 4
  • 33
  • 42
  • Not sure if this is related, but does it pin the string before it lets it cross the boundary? – Sam Saffron May 05 '09 at 14:51
  • If by pin you mean like a fixed {} block, then no, pinning is only used when sending object references into unmanaged territory. – Yona May 05 '09 at 15:16

3 Answers3

8

Marshalling is actually fairly tricky.

The behaviour you are describing is called "marshal-by-bleed", the runtime uses it to marshal strings (sometimes) and marshal System.Threading.Thread ALWAYS.

As far as I can tell you have no control over this (its mentioned in the article that you can define custom marshalling behaviour but I can not find any documentation on it), you could potentially pass an IntPtr around and use unsafe code to simulate this, but it smells like a huge hack to me.

Sam Saffron
  • 128,308
  • 78
  • 326
  • 506
  • 1
    big +1 for the link, Marshall by Bleed is interesting – ShuggyCoUk May 06 '09 at 09:04
  • You can implement custom marshal-by-bleed with a bit of trickery: https://bitbucket.org/kgtinv/kgtpublic_utils/src/49ec9be278a7cff65838a42069eeef85f248a9ad/src/Kreslik.Integrator.LowLatencyUtils/CrossAppDomainData.cs#lines-17 – Jan Nov 17 '19 at 20:27
  • Quick description: make one AppDomain ('master') own the data, then form other app domains ('slaves') call into that, let it give you the memory address and in the destination domain wrap it into full blown GC object. You have to control that no GC occured during this process (which is quite quick and you can retry otherwise) and you should prevent GC collecting of this wrapper in 'slave' AppDomains – Jan Nov 17 '19 at 20:28
  • Jan's link is dead. Here's another article explaining how to achieve marshal by bleed. http://geekswithblogs.net/akraus1/archive/2012/07/25/150301.aspx – Robert Schmidt Nov 27 '19 at 21:00
0

I don't think so, no. I believe that this, like the primitives, is handled directly by the runtime.

Marc Gravell
  • 1,026,079
  • 266
  • 2,566
  • 2,900
  • This is wrong, as described here: http://geekswithblogs.net/akraus1/archive/2012/07/25/150301.aspx – Robert Schmidt Nov 27 '19 at 20:55
  • @Robert I'm happy to stand corrected. I'm even happier to say that since app-domains are now obsolete (.net core, etc) it is moot :) – Marc Gravell Nov 27 '19 at 21:13
  • Well, a few of us are still needing to dabble with .NET Framework for years to come. Digging up ancient knowledge from SO and defunct blogs is becoming a forensics art form – Robert Schmidt Dec 03 '19 at 19:01
-1

You only have two marshaling semantics in .NET Remoting: marshal by value (SerializableAttribute) and marshal by reference (MarshalByRef).

As you alluded to, strings are marshaled by value, as System.String is decorated with the SerializableAttribute.

If you want to pass your object between app domains and you want just a copy (no changes in on the object in the remote app domain affect the object in the local app domain) then what you want is to use the SerializableAttribute on your class.

Hope this helps.