Delegate and execute delegate in a separate AppDomain

I want to exclude part of the code in a separate AppDomain with a delegate. How can i do this?

UPD1 : some details about my problem My program processes some data (one iteration: getting some data from the database, evaluating it and creating assemblies at runtime, performing dynamic assemblies and writing the results to the database).

Current solution: each iteration is performed in a separate thread. Best solution: each iteration is performed in a separate AppDomain (for unloading dynamic asseblies).

UPD2 : that's it, thanks for the answers.

I found one for me in this thread: Replacing Process.Start with AppDomains

+29
c # delegates appdomain
Jan 05 '10 at 20:01
source share
4 answers

Although you can make a call to a delegate that will be handled by a separate AppDomain, I personally always used the CreateInstanceAndUnwrap method, which creates an object in a foreign application domain and returns a proxy to it.

To do this, your object must inherit from MarshalByRefObject.

Here is an example:

public interface IRuntime { bool Run(RuntimesetupInfo setupInfo); } // The runtime class derives from MarshalByRefObject, so that a proxy can be returned // across an AppDomain boundary. public class Runtime : MarshalByRefObject, IRuntime { public bool Run(RuntimeSetupInfo setupInfo) { // your code here } } // Sample code follows here to create the appdomain, set startup params // for the appdomain, create an object in it, and execute a method try { // Construct and initialize settings for a second AppDomain. AppDomainSetup domainSetup = new AppDomainSetup() { ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase, ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile, ApplicationName = AppDomain.CurrentDomain.SetupInformation.ApplicationName, LoaderOptimization = LoaderOptimization.MultiDomainHost }; // Create the child AppDomain used for the service tool at runtime. childDomain = AppDomain.CreateDomain( "Your Child AppDomain", null, domainSetup); // Create an instance of the runtime in the second AppDomain. // A proxy to the object is returned. IRuntime runtime = (IRuntime)childDomain.CreateInstanceAndUnwrap( typeof(Runtime).Assembly.FullName, typeof(Runtime).FullName); // start the runtime. call will marshal into the child runtime appdomain return runtime.Run(setupInfo); } finally { // runtime has exited, finish off by unloading the runtime appdomain if(childDomain != null) AppDomain.Unload(childDomain); } 

In the above example, it is encoded to execute the Run method, which is passed in some installation information, and the completion of the Run method is determined to indicate that all the code in the child domain of the AppDomain is complete, so we finally have a block that enables the unloading of the AppDomain.

Often you can be careful what types you place in assemblies - you can use the interface and put it in a separate assembly, which both the calling program (our code that installs the application and calls it) and the developer (Runtime class) depend on. This IIRC allows the parent AppDomain to load only the assembly containing the interface, while the child domain appdomain loads both the assembly containing Runtime and its dependency (IRuntime assembly). Any custom types that are used by the IRuntime interface (for example, our RuntimeSetupInfo class) should usually also be placed in the same assembly as IRuntime. Also, be careful how you define these custom types β€” if they are data objects (probably RuntimeSetupInfo), you should probably mark them with the [serializable] attribute β€” so that a copy of the object is passed (serialized from the parent appdomain for a child). You want to avoid redirecting calls from one application to another, as it is rather slow. Passing a DTO by value (serialization) means that accessing the values ​​in the DTO does not require an internetwork call (since the child appdomain has its own copy of the original). Of course, this also means that cost changes are not reflected in the original source DTO of the parent application.

As encoded in the example, the parent appdomain will actually load both the IRuntime and Runtime assemblies, but this is because when I call CreateInstanceAndUnwrap I use typeof (Runtime) to get the assembly name and full type name. Instead, you can hard-code or Extract these lines from the file, which separates the dependency.

There is also a method in AppDomain called "DoCallBack" that looks like it allows you to call a delegate in a foreign AppDomain. However, the type of delegate that it accepts is of type "CrossAppDomainDelegate". The definition of which:

 public delegate void CrossAppDomainDelegate() 

Thus, it will not allow you to transfer any data to it. And, since I never used it, I can’t tell you if there are any special problems.

In addition, I would recommend exploring the LoaderOptimization property. What you set for this can significantly affect performance, since some settings of this property force the new appdomain to load separate copies of all assemblies (and their JITs, etc.), even if (IIRC) the assembly is in the GAC (i.e. E. This includes CLR assemblies). This can give you terrible performance if you use a large number of assemblies from your child application. For example, I used WPF from child domains, which caused big launch delays for my application, until I set a more suitable download policy.

+46
Jan 05 '10 at 22:09
source share

To delegate to another AppDomain, you can use System.AppDomain.DoCallBack () . A great example is the linked MSDN page. Please note that you can only use delegates like CrossAppDomainDelegate .

+8
Jan 14 '13 at 14:12
source share

You need to read .NET Remoting, and in particular, Remote Objects , as that is all you can get through AppDomains.

Long and short is that your object is either passed by value or by reference (via a proxy).

By value, your object is required to be Serializable. Delegates are not serializable afaik. This means that this is not a good way.

The link requires you to inherit from MarshalByRefObject . Thus, the remote infrastructure can create a proxy server. However, this also means that your delegate will be executed on the machine that creates it, and not in the client application domain.

In general, it will be difficult. Perhaps you should consider making your delegates full serializable objects so that they can be easily moved with deletion (and will work well with other technologies).

+6
Jan 05 '10 at 20:17
source share

This does not answer your question directly, but it might be better to create a WCF service or a web service in another AppDomain to maintain isolation. I do not know your specific situation, but isolated architectural design is almost always the right way.

+3
Jan 05
source share



All Articles