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



我试图使用AppDomains以便在我的应用程序中隔离和运行代码。我需要做的是为每个客户端创建新的AppDomain,并在该AppDomain下,我需要创建另一个类的实例,其中包含需要隔离的代码。我还需要以某种方式存储创建的实例,以便稍后创建它的同一客户机再次调用时可以访问它。我现在创建它的方法是:

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);
}

AppDomain的创建和"Initiliaze(clientId)"方法的首次调用工作正常。此外,将其存储在字典中(供以后使用)也没有任何例外。

当我稍后尝试获取先前创建的IsolatedClass的实例时,出现问题,如下所示:

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

抛出空引用异常(无法检索实例)。当我在那里放置一个断点并检查字典内的内容时,对于Value,它告诉我:"在此上下文中不支持获取透明代理的运行时类型。"

这是完全错误的方法还是只是一些小错误?如果我的方法是完全错误的,还有其他的方法来实现我的目标吗?


编辑

显然,IsolatedClass本身有一些问题-它继承了另一个继承了MarshallByRefObject的类。当我创建了一个简单的虚拟类,并按照Kentonbmax的指令进行操作时,它起作用了。我将继续测试,看看真正的问题是什么。

我尝试了这个,唯一的区别是我的类在不同的库中。如果你想与不同的类类型进行交互,你可以用MarshalByRefObject代替IsolatedClass作为字典中的值类型。

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

UnhandledException和DomainUnload事件在你的IsolatedClass是一个很好的方式来处理任何资源在你的IsolatedClass卸载你的AppDomains。另外,我建议使用'as'代替直接强制转换,这样你就可以检查强制转换是否失败,而不会抛出InvalidCast异常。

使用。first是有问题的,因为您不能保证键存在,因此可以返回空引用。如果你在调用Initialize时知道clientId为什么在调用DoSomething时不知道呢?

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

相关内容

  • 没有找到相关文章

最新更新