我有一个应用程序需要在许多AppDomain之间发送适量的消息.我知道我可以使用远程处理实现这一点,但我也注意到有跨域委托.谁有人看过这种问题?
我正在编写一个工具来报告有关在我的客户端系统中的环境和区域部署的.NET应用程序的信息.
我想阅读这些程序集中的程序集属性的值.
这可以使用Assembly.ReflectionOnlyLoad,但是即使这种方法也可以保持装配.这里的问题是我无法从不同的路径加载两个具有相同名称的程序集,因此我无法比较在不同系统中部署的相同应用程序.
在这一点上,我假设解决方案将涉及使用临时AppDomains.
有人可以详细说明如何将程序集加载到另一个程序集中AppDomain,从中读取属性然后卸载AppDomain?
这需要适用于文件系统上的程序集以及URL地址上的程序集.
我想动态加载一个或多个DLL,以便它们使用与我的主应用程序不同的安全性或基本路径运行.如何将这些DLL加载到单独的AppDomain中并从中实例化对象?
我想用委托在单独的AppDomain中区分一些代码.我怎样才能做到这一点?
UPD1:关于我的问题的更多细节我的程序处理一些数据(一次迭代是:从DB获取一些数据,评估它并在运行时创建程序集,执行动态程序集并将结果写入DB).
当前解决方案:每个迭代在单独的线程中运行.更好的解决方案:每个迭代在单独的AppDomain中运行(卸载动态组件).
UPD2:全部,谢谢你的回答.
我在这个帖子中找到了一个: 用AppDomains替换Process.Start
我有一些C#代码使用CSharpCodeProvider.CompileAssemblyFromSource在内存中创建一个程序集.在对程序集进行垃圾回收之后,我的应用程序使用的内存比创建程序集之前的内存要多.我的代码在ASP.NET Web应用程序中,但我在WinForm中重复了这个问题.我正在使用System.GC.GetTotalMemory(true)和Red Gate ANTS Memory Profiler来测量增长(使用示例代码大约600个字节).
从我的搜索开始,听起来泄漏来自新类型的创建,而不是来自我所持有的任何对象.我发现的一些网页提到了有关AppDomain的一些内容,但我不明白.有人可以解释这里发生了什么以及如何解决它?
以下是泄漏示例代码:
private void leak()
{
CSharpCodeProvider codeProvider = new CSharpCodeProvider();
CompilerParameters parameters = new CompilerParameters();
parameters.GenerateInMemory = true;
parameters.GenerateExecutable = false;
parameters.ReferencedAssemblies.Add("system.dll");
string sourceCode = "using System;\r\n";
sourceCode += "public class HelloWord {\r\n";
sourceCode += " public HelloWord() {\r\n";
sourceCode += " Console.WriteLine(\"hello world\");\r\n";
sourceCode += " }\r\n";
sourceCode += "}\r\n";
CompilerResults results = codeProvider.CompileAssemblyFromSource(parameters, sourceCode);
Assembly assembly = null;
if (!results.Errors.HasErrors)
{
assembly = results.CompiledAssembly;
}
}
Run Code Online (Sandbox Code Playgroud)
更新1:此问题可能相关:动态加载和卸载使用CSharpCodeProvider生成的all
更新2:尝试更多地了解应用程序域,我发现: …
c# memory-leaks appdomain marshalling compileassemblyfromsource
我正在尝试使用AppDomain管理一些遗留代码的想法,其中包含许多静态字段在多线程环境中.
我读到了这个问题的答案:如何使用AppDomain限制静态类的范围以便线程安全使用?,认为它非常有前景,并决定在程序集ClassLibrary1.dll中使用一个非常简单的类来尝试它:
namespace ClassLibrary1
{
public static class Class1
{
private static int Value = 0;
public static void IncrementAndPrint()
{
Console.WriteLine(Value++);
}
}
}
Run Code Online (Sandbox Code Playgroud)
这是我的代码,它将程序集加载到2个不同的应用程序域并多次调用IncrementAndPrint():
var appDomain1 = System.AppDomain.CreateDomain("AppDomain1");
var appDomain2 = System.AppDomain.CreateDomain("AppDomain2");
var assemblyInAppDomain1 = appDomain1.Load("ClassLibrary1");
var assemblyInAppDomain2 = appDomain2.Load("ClassLibrary1");
var class1InAppDomain1 = assemblyInAppDomain1.GetType("ClassLibrary1.Class1");
var class1InAppDomain2 = assemblyInAppDomain2.GetType("ClassLibrary1.Class1");
class1InAppDomain1.InvokeMember("IncrementAndPrint", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, null);
class1InAppDomain1.InvokeMember("IncrementAndPrint", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, null);
class1InAppDomain1.InvokeMember("IncrementAndPrint", BindingFlags.Static | BindingFlags.Public | BindingFlags.InvokeMethod, null, null, null);
class1InAppDomain2.InvokeMember("IncrementAndPrint", …Run Code Online (Sandbox Code Playgroud) 当EF尝试从App.config加载信息时,我最近开始在我的单元测试(NUnit)代码中遇到以下异常:
System.Runtime.Serialization.SerializationException : Type is not resolved for member [my type name], [my assembly name]
Run Code Online (Sandbox Code Playgroud)
NUnit GUI运行器和R#的VS集成运行器都会发生这种情况.这是一个快速的单元测试,可以重现这个问题:
[Test]
public void Test()
{
// adding
// ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
// here fixes things, probably because the configuration is cached
CallContext.LogicalSetData("FooSlot", new Foo()); // removing this line fixes things
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None); // fails with above exception
}
[Serializable] // removing this gives a different exception complaining that Foo is not Serializable
public class Foo // : MarshalByRefObject // this fixes things
{
}
Run Code Online (Sandbox Code Playgroud)
使用融合日志查看器,我发现失败是由于
FILE_NOT_FOUND …
我在facebook应用程序中将我的生产服务器IP地址作为App域提供,但它没有保存.它因App域无效而返回错误.所以我不能使用我的facebook连接API.
我们可以在FB应用程序中将IP地址作为App域吗?如果不是,那么另一种方法是什么?
最近我的重点是创建一个可以托管第三方MVC插件的ASP.NET MVC应用程序.理想情况下,这些插件的开发将遵循以下规则:
经过一番研究后,我想出了以下几种方法来实现这一点,每种方法各有优缺点.
工作流程
PreApplicationStartMethodAttribute,MEF或主机项目中的基本组件参考(如果可能).Area主机内的插件.好处
PreApplicationStartMethodAttribute,项目引用)之前和应用程序启动之后(MEF),将程序集包含到主机App Domain中很简单缺点
结论
这是最简单的方法,但它也是最不安全的方法.它基本上消除了允许不受信任的开发人员创建插件的可能性,因为这些插件将具有与宿主应用程序相同的信任级别(这意味着如果宿主应用程序可以执行诸如System.IO.File.Delete插件之类的方法)
这种方法旨在允许创建可以沙箱化为自己的MVC插件,AppDomains并由主机通过System.Addin库使用.
结构体
在主机中设置路由,以确定正在处理的URL是否针对插件.可能有这样的模式example.com/p/{plugin}/{controller}/{action}/{id}
具有上述模式的所有路由都映射到具有模块路由操作的主机控制器.该操作会查看任何给定的路由,并根据段确定处理请求的相应插件{plugin}.
插件视图是一个接收器/发送器对象,充当插件控制器的网关.它有一个名为AcceptRequest的方法,它RequestContext从主机接收a ,并返回一个ActionResult.
插件管道包含可以串行化RequestContext并ActionResult跨管道隔离边界传输的适配器.
执行流程
匹配插件的路由并调用插件路由控制器.
控制器将所需的插件加载到它自己的插件中AppDomain并调用AcceptRequest,通过RequestContext(通过管道序列化)
AcceptRequest接收上下文并根据该请求确定要执行的适当控制器(使用自定义控制器工厂).
一旦控制器完成执行请求,它就会ActionResult向接收器对象返回一个接收器对象,然后将该接收器对象 …
我有
public static class A
{
public static string ConnString;
}
[Serializable]
public class Test{
// Accesing A's field;
public string ConnString{get{return A.ConnString;}set{A.ConnString=value;}}
}
void Main()
{
A.ConnString = "InitialString"; // I set A.ConnString in the current domain
var newDomain = AppDomain.CreateDomain("DomNew");
Test TObj = newDomain.CreateInstanceAndUnwrap(typeof(Test).Assembly.FullName, typeof(Test).FullName) as Test ;
TObj.ConnString = "NewDomainString"; // It is supposed to set A.ConnString in the newDomain aka a different instance of A.ConnString
// Here it is supposed to print two different values
Console.WriteLine(A.ConnString); …Run Code Online (Sandbox Code Playgroud) appdomain ×10
c# ×7
.net ×4
asp.net ×1
asp.net-mvc ×1
assemblies ×1
delegates ×1
facebook ×1
fbconnect ×1
instance ×1
marshalling ×1
memory-leaks ×1
nunit ×1
plugins ×1
remoting ×1
static ×1
variables ×1