应用程序域和应用程序池有什么区别?
我读过很多关于这两个术语的文章.但仍然无法正确理解它们.
请用简单的描述详细说明.
谢谢
当我执行AppDomain.Unload(myDomain)时,我希望它也可以执行完整的垃圾回收.
根据Jeffrey Richter在"CLR via C#"中的说法,他说在AppDomain.Unload期间:
CLR强制进行垃圾收集,回收由现在卸载的AppDomain创建的任何对象使用的内存.调用这些对象的Finalize方法,使对象有机会正确地清理自己.
根据"自定义.NET Framework公共语言运行时"中的"Steven Pratschner":
在所有终结器运行并且域中不再执行任何线程之后,CLR就可以卸载内部实现中使用的所有内存中数据结构.但是,在此之前,必须收集驻留在域中的对象.发生下一次垃圾收集后,将从进程地址空间卸载应用程序域数据结构,并将该域视为已卸载.
我误解了他们的话吗?我做了以下解决方案来重现意外行为(在.net 2.0 sp2中):
一个名为"Interfaces"的类库项目,包含此接口:
public interface IXmlClass
{
void AllocateMemory(int size);
void Collect();
}
Run Code Online (Sandbox Code Playgroud)
一个名为"ClassLibrary1"的类库项目,它引用了"Interfaces"并包含了这个类:
public class XmlClass : MarshalByRefObject, IXmlClass
{
private byte[] b;
public void AllocateMemory(int size)
{
this.b = new byte[size];
}
public void Collect()
{
Console.WriteLine("Call explicit GC.Collect() in " + AppDomain.CurrentDomain.FriendlyName + " Collect() method");
GC.Collect();
Console.WriteLine("Number of collections: Gen0:{0} Gen1:{1} Gen2:{2}", GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2));
}
~XmlClass()
{
Console.WriteLine("Finalizing in AppDomain {0}", AppDomain.CurrentDomain.FriendlyName);
}
} …
Run Code Online (Sandbox Code Playgroud) 我有一个可以一次由多个进程使用的程序集.如果我使用的是静态类,那么多个进程是否都使用该类的相同"实例"?
由于这些进程是分开的,它们是否会在不同的应用程序域下运行,因此静态"实例"是否分开?
这里的细节中的布丁是一个自定义BizTalk适配器正在使用该程序集,我将其设置为以并行批处理方式处理消息.这就是我所说的"多个过程".
什么是应用程序域(AppDomain),它与进程或线程有什么不同?
我在代码库中有一些依赖于Application.Current.Dispatcher.Invoke ...的方法来确保在GUI线程上运行.我目前正在尝试为这些方法编写单元测试但是(正如预期的那样)Application.Current为null所以我得到一个NullReferenceException.
我试图在他们自己的AppDomain中运行受影响的测试,如下所示:http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/786d5c06-0511-41c0-a6a2-5c4e44f8ffb6/
但是当我这样做时,Application.Current仍为null.不应该启动AppDomain为我设置Application.Current?为什么它仍然是空的?
我的代码:基类:
[TestClass()]
[Serializable]
public class UnitTest
{
protected void ExecuteInSeparateAppDomain(string methodName)
{
AppDomainSetup appDomainSetup = new AppDomainSetup();
appDomainSetup.ApplicationBase = Environment.CurrentDirectory;
AppDomain appDomain = AppDomain.CreateDomain(methodName, null, appDomainSetup);
try
{
appDomain.UnhandledException += delegate(object sender, UnhandledExceptionEventArgs e)
{
throw e.ExceptionObject as Exception;
};
UnitTest unitTest = appDomain.CreateInstanceAndUnwrap(GetType().Assembly.GetName().Name, GetType().FullName) as UnitTest;
MethodInfo methodInfo = unitTest.GetType().GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
if (methodInfo == null)
{
throw new InvalidOperationException(string.Format("Method '{0}' not found on type '{1}'.", methodName, unitTest.GetType().FullName));
}
try
{ …
Run Code Online (Sandbox Code Playgroud) 我正在尝试使用应用程序域从控制台应用程序启动WPF应用程序,但是当我这样做时,我收到意外错误.
可以独立运行WPF应用程序.
这段代码也适用:
var baseDirectory = AppDomain.CurrentDomain.BaseDirectory;
var path = string.Format("{0}AddressbookDesktop.exe", baseDirectory);
var processInfo = new ProcessStartInfo(path, "");
Process.Start(processInfo);
Run Code Online (Sandbox Code Playgroud)
但是此代码失败并出现以下错误.错误似乎在构造函数中,该构造函数为空:
var addressbookDomain = AppDomain.CreateDomain("addressbookDomain");
addressbookDomain.ExecuteAssembly("AddressbookDesktop.exe");
Run Code Online (Sandbox Code Playgroud)
堆栈跟踪:
System.Windows.Markup.XamlParseException: Cannot create instance of
'AddressbookMainWindow' defined in assembly 'AddressbookDesktop, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null'. Exception has been thrown
by the target of an invocation. Error in markup file 'AddressbookMainWindow.xaml' Line 1 Position 9.
---> System.Reflection.TargetInvocationException: Exception has been thrown by the
target of an invocation. ---> System.InvalidOperationException: The calling thread must
be STA, because many …
Run Code Online (Sandbox Code Playgroud) 在AS3中,它是ApplicationDomain.domainMemory
为了什么?
我的公司拥有大量客户,我们目前能够为每台服务器处理有限数量的客户.但是,每个客户端都使用相同的核心Web应用程序.目前,一些内容存储在每个站点的本地,因此我们不能使用相同的站点/应用程序池; 虽然我们确实有一个多租户转换项目.
我们强烈签署了所有程序集,我认为看看我们是否可以让它们在ASP.NET中加载域中性是一个有趣的想法.这样做的好处是显着降低了我们的内存成本,这是我们目前最高的成本/限制因素之一.此外,似乎我们能够简化当前[编译] IO/CPU绑定的部署过程,并且经常花费我们大约6个小时.
此任务意味着我希望将程序集从App池的应用程序域中的加载移动到共享域.
我对域中性加载要求的理解是:
我试图让它工作,但我不能让它适用于一个小样本应用程序.我首先尝试将Newstonsoft.Json放入GAC,令我兴奋的是,它在回收后转移到共享域.但是,即使在对所有其他域进行GAC操作之后,我也无法让任何其他人转到共享域:
我的目标是让我的主应用程序DLL加载域中性.我如何调试/继续前进,找出为什么剩余的Assemblies没有被加载为域中立?
另外,我对NGEN代码页共享如何关联或与共享域加载的程序集形成对比有点困惑.
何时在应用程序中创建新的应用程序域有哪些指导原则和最佳实践?
此外,在应用程序中如何使用多个应用程序域的一些常见用途和示例是什么?
请考虑以下代码:
// Create a new application domain
AppDomain ad = AppDomain.CreateDomain("New domain");
Worker work = new Worker();
// if Worker class is marked as 'MarshalByRefObject', this will run in current
// appdomain.
// if Worker class is NOT marked as 'MarshalByRefObject' and is marked as
// 'Serializable', this will run in a new appdomain.
ad.DoCallBack(work.PrintDomain);
// or ad.DoCallBack(new CrossAppDomainDelegate(work.PrintDomain));
// But for static methods:
// If ppp method is static, no marking is required and it will run in
// …
Run Code Online (Sandbox Code Playgroud)