简体   繁体   English

存储在AppDomain下创建的对象的实例

[英]Storing instance of object created under AppDomain

Iam trying to use AppDomains in order to isolate and run code in my application. 我试图使用AppDomains来隔离并在我的应用程序中运行代码。 What I need to do, is to create new AppDomain for each client and under that AppDomain, I need to create instance of another class which contains the code that needs to be isolated. 我需要做的是为每个客户端创建新的AppDomain,在该AppDomain下,我需要创建另一个类的实例,该实例包含需要隔离的代码。 I also need to somehow store that created instance, so that I can access it later when the same client that created it calls again. 我还需要以某种方式存储创建的实例,以便稍后在创建该实例的同一客户端再次调用时可以访问它。 The way Im creating it now is this: 我现在创建它的方式是:

private Dictionary<string, IsolatedClass> isolatedClassesList = new Dictionary<string, IsolatedClass>();

public void Initialize(string clientId)
{
    AppDomain appDomain = AppDomain.CreateDomain("New AppDomain");

    IsolatedClass isolatedClass = (IsolatedClass)appDomain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(IsolatedClass).FullName);

    isolatedClass.Initialize(clientId);

    isolatedClassesList.Add(clientId, isolatedClass);
}

The creation of AppDomain and first call of " Initiliaze(clientId) " method works fine. AppDomain的创建和“ Initiliaze(clientId) ”方法的首次调用都可以正常工作。 Also storing it in the dictionary (for later use) is done without any exceptions. 还将其存储在字典中(以备后用)也没有任何例外。

The problem occurs when I try to get the instance of previously created IsolatedClass later, like that: 当我稍后尝试获取以前创建的IsolatedClass的实例时,会发生此问题:

public void DoSomething (string clientId)
{
    IsolatedClass isolatedClass = isolatedClassesList.First(x => x.Key == clientId).Value;

    isolatedClass.RunIsolatedMethod();
}

It throws null refference exception (it cannot retrieve the instance). 它引发空引用异常(无法检索实例)。 When I put a breakpoint there and check what is inside the dictionary, for Value , it shows me that: "Obtaining the runtime type of a transparent proxy is not supported in this context." 当我在其中放置一个断点并检查字典中的内容时,对于Value ,它表明:“在这种情况下,不支持获取透明代理的运行时类型。”

Is this totally wrong approach or is there just some minor mistake? 这是完全错误的方法还是只有一些小错误? If my approach is totally wrong, is there any other way how to achieve my goal? 如果我的方法完全错误,还有其他方法可以实现我的目标吗?


EDIT 编辑

Apparently, there was some issue with the IsolatedClass itself - it was inheriting from another class which was inheriting from MarshallByRefObject. 显然, IsolatedClass本身存在一些问题-它是从另一个类继承而来的,该类是从MarshallByRefObject继承的。 When I created simple dummy class and procceded with instruction from Kentonbmax, it worked. 当我创建简单的虚拟类并接受Kentonbmax的指导时,它就可以工作。 I will continue testing to see, what was the real issue. 我将继续测试,看看真正的问题是什么。

I tried this and the only difference is that my class is inside of a different library. 我尝试了这一点,唯一的区别是我的课程位于其他库中。 You can replace IsolatedClass with MarshalByRefObject as your value type in your dictionary if you have different class types you want to interact with. 如果您要与之交互的类类型不同,则可以将MarshalByRefObject的IsolatedClass替换为字典中的值类型。

var domain = AppDomain.CreateDomain(typeof(MyType).Assembly.FullName);

                    var proxy = domain.CreateInstanceAndUnwrap(
                        typeof(MyType).Assembly.FullName,
                        typeof(MyType).FullName) as MyType;

UnhandledException and DomainUnload events inside of your IsolatedClass are a good way to dispose of any resources in your IsolatedClass when unloading your AppDomains. 在卸载AppDomain时,IsolatedClass内部的UnhandledException和DomainUnload事件是处置IsolatedClass中任何资源的好方法。 Also I recommend using 'as' instead of a direct cast this way you can check to see if the cast failed without throwing an InvalidCast Exception. 另外,我建议使用“ as”代替直接转换,这样您可以检查转换是否失败而不会引发InvalidCast异常。

Using .First is problematic because you are not guaranteed that the key exists and can therefore get back a null reference. 使用.First是有问题的,因为不能保证该键存在,因此可以返回空引用。 If you know the clientId when you call Initialize why do you not know it when you call DoSomething? 如果在调用Initialize时知道clientId,为什么在调用DoSomething时却不知道呢?

if(_isolatedClassesList.ContainsKey(clientId)
{
    MyType mine = _isolatedClassesList[clientId] as MyType;
    mine.MyMethod();
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM