Fir*_*iro 5 .net c# applicationdomain
我使用Applicationdomain动态加载一个DLL,以便在nessesary时卸载.如果加载的dll中的任务终止,那么我无法工作的是来自创建的Appdomain的回调方法.
到目前为止我有什么
public interface IBootStrapper
{
void AsyncStart();
void StopAndWaitForCompletion();
event EventHandler TerminatedItself;
}
Run Code Online (Sandbox Code Playgroud)
和"初学者"方面
private static Procedure CreateDomainAndStartExecuting()
{
AppDomain domain = AppDomain.CreateDomain("foo", null, CODEPATH, string.Empty, true);
IBootStrapper strapper = (IBootStrapper)domain.CreateInstanceAndUnwrap(DYNAMIC_ASSEMBLY_NAME, CLASSNAME);
strapper.ClosedItself += OnClosedItself;
strapper.AsyncStart();
return delegate
{
strapper.StopAndWaitForCompletion();
AppDomain.Unload(domain);
};
}
Run Code Online (Sandbox Code Playgroud)
这导致程序集未找到异常,因为OnClosedItself()是一个只有Starter知道的类型的方法,它在appdomain中不存在.
如果我将OnClosedItself作为委托包装在一个可序列化的类中,它就是一样的.
有什么建议?
编辑:我正在尝试做的是建立一个自我更新的任务.因此我创建了一个启动器,如果有新版本可以停止并重新创建任务.但是如果任务从其他地方停止,它也应该通知启动器终止.
//从问题中删除了大量临时代码
编辑2:哈普洛指出我正确的方向.我能够用信号量实现回调.
我通过使用具有共享类型的第三个程序集(在您的例子中是 IBoostrapper 的实现)解决了这种情况。就我而言,我有更多的类型和逻辑,但对你来说,只为一种类型创建一个程序集可能有点矫枉过正......
也许您更喜欢使用共享的互斥体?然后您可以同步 2 个 AppDomains 任务...
编辑:
您正在主 Appdomain 上创建互斥体,并且也是最初拥有的,因此它永远不会在 WaitOne() 上停止,因为您已经拥有它。
例如,您可以在 IBootstrapper 实现类内的生成的 Appdomain 上创建互斥体(与最初拥有的一样)。CreateInstanceAndUnwrap调用返回后,互斥锁应该存在并且由 Bootstrapper 拥有。因此,您现在可以打开互斥体(调用OpenExisting,以便确定您正在共享它),然后您可以对其进行 WaitOne。一旦生成的 AppDomain 引导程序完成,您就可以释放互斥体,主 Appdomain 将完成工作。
互斥体是系统范围的,因此它们可以跨进程和应用程序域使用。看看MSDN Mutex的备注部分
编辑:如果您无法使其与互斥体一起使用,请参阅下一个使用信号量的简短示例。这只是为了说明这个概念,我没有加载任何额外的程序集等......默认 AppDomain 中的主线程将等待信号量从生成的域中释放。当然,如果您不希望主AppDomain终止,则不应允许主线程退出。
class Program
{
static void Main(string[] args)
{
Semaphore semaphore = new Semaphore(0, 1, "SharedSemaphore");
var domain = AppDomain.CreateDomain("Test");
Action callOtherDomain = () =>
{
domain.DoCallBack(Callback);
};
callOtherDomain.BeginInvoke(null, null);
semaphore.WaitOne();
// Once here, you should evaluate whether to exit the application,
// or perform the task again (create new domain again?....)
}
static void Callback()
{
var sem = Semaphore.OpenExisting("SharedSemaphore");
Thread.Sleep(10000);
sem.Release();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1600 次 |
| 最近记录: |