我有一种情况需要创建一个(可以说是脏的)浸泡测试运行器。想法是使用诸如Tasks或ThreadPool之类的东西来同时运行大量的测试。
问题在于它将使用很多(由我开发的)辅助类,它们在其中使用静态。这从来都不是问题,因为一切都被拆除并在使用后重新启动。这意味着当我在同一个应用程序域中启动多个线程时,它们会使用相同的静态,而且事情会变得混乱。
注意:这是基于我一直在做的测试的假设,我不是100%肯定这就是问题。
我尝试创建一个新的AppDomain(AppDomain.Create),然后使用它创建一个类的实例(domain.CreateInstanceFromAndUnwrap),然后创建实例,我可以在其上调用方法。问题是它似乎没有在新的AppDomain中运行。
这是我到目前为止的代码:
static void CallBack(BasePerfTest bpf)
{
Console.WriteLine("CurrentAppDomain (WithinCallback): {0}", Thread.GetDomain().Id);
AppDomain newdomain = AppDomain.CreateDomain(Guid.NewGuid().ToString());
//newdomain.ExecuteAssembly(".\\PerformanceTestRunner.exe", new string[] { bpf.ToString() });
ProcessRunner pr = (ProcessRunner)newdomain.CreateInstanceFromAndUnwrap(Assembly.GetExecutingAssembly().Location, "PerformanceTesting.ProcessRunner");
pr.RunProcess(bpf);
}
}
[Serializable]
public class ProcessRunner
{
public void RunProcess(BasePerfTest bpf)
{
Console.WriteLine("CurrentAppDomain (WithinPR): {0}", Thread.GetDomain().Id);
}
}
现在,我希望RunProcess()方法在域中执行,但DomainID仍然是相同的,因此它会遇到静态冲突的问题。
现在,我确实创建了一个单独的控制台应用程序,注释掉的行显示了我用来运行它的代码。此DID在新域中运行,但问题是原因。
我很高兴能够指出一些睡前阅读的方向,这是关于它是如何工作的,我已经过去一天了,我想我一定不能使用正确的术语。
非常感谢任何帮助。
谢谢, 马丁
答案 0 :(得分:4)
有两种方法可以通过AppDomain边界公开对象:
Serializable
- 序列化对象,以便获得副本。MarshalByRefObject
- 使用远程处理为您的对象创建代理。您的ProcessRunner
课程需要后者。
让您的班级继承自MarshalByRefObject
:
public class ProcessRunner : MarshalByRefbject
{
public void RunProcess(BasePerfTest bpf)
{
Console.WriteLine("CurrentAppDomain (WithinPR): {0}", Thread.GetDomain().Id);
}
}
当您在第二个AppDomain中实例化您的类时,您将获得一个代理。 MSDN上MarshalByRefObject
文档中的示例也应该对您有所帮助 - 它几乎可以证明您正在尝试做什么。
答案 1 :(得分:2)
您的ProcessRunner类必须从System.MarshalByRefObject继承。发生的事情是该对象实际上是在辅助应用程序域中创建的,但是当您将其分配给本地“pr”变量时,它会通过值将其编组回您的主应用程序域,实际上会在其中创建ProcessRunner的第二个实例。主appdomain。如果从MarshalByRefObject继承,那么pr将获得一个透明的代理对象,该对象将调用转发给驻留在辅助appdomain中的对象。