gpt4 book ai didi

c# - 在 .net 中通过 ApplicationDomain 边界实现回调

转载 作者:太空狗 更新时间:2023-10-29 23:03:05 24 4
gpt4 key购买 nike

我使用 Applicationdomain 动态加载一个 dll,以便在需要时卸载。如果加载的 dll 中的任务自行终止,我无法开始工作的是来自创建的 Appdomain 的回调方法。

到目前为止我有什么

public interface IBootStrapper
{
void AsyncStart();
void StopAndWaitForCompletion();

event EventHandler TerminatedItself;
}

和“入门”方面

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

这会导致程序集未找到异常,因为 OnClosedItself() 是一种只有 Starter 知道的类型的方法,它不存在于应用程序域中。

如果我将 OnClosedItself 包装为可序列化类中的委托(delegate),则情况相同。

有什么建议吗?

编辑:我想做的是构建一个 self 更新任务。因此我创建了一个启动程序,如果有新版本可用,它可以停止并重新创建任务。但如果任务从其他地方停止,它也应该通知启动器终止。

//从问题中剥离了很多临时代码

编辑 2:Haplo 为我指明了正确的方向。我能够使用信号量实现回调。

最佳答案

我通过使用具有共享类型的第三个程序集 解决了这种情况(在您的例子中是 IBoostrapper 的实现)。在我的例子中,我有更多的类型和逻辑,但对你来说,只为一种类型设置一个程序集可能有点矫枉过正......

也许您更愿意使用共享命名互斥体?然后您可以同步 2 个 AppDomains 任务...

编辑:

您正在主 Appdomain 上创建互斥量,并且作为初始拥有,因此它永远不会在 WaitOne() 上停止,因为您已经拥有它。

例如,您可以在 IBootstrapper 实现类内的派生 Appdomain 上创建 Mutex,就像最初拥有的那样。在 CreateInstanceAndUnwrap 调用返回后,互斥体应该存在并且由 Bootstrapper 拥有。所以您现在可以打开互斥量(调用 OpenExisting 以确保您正在共享它),然后您可以在其上等待一个。生成的 AppDomain Bootstrap 完成后,您可以释放互斥锁,主 Appdomain 将完成工作。

互斥量是系统范围的,因此它们可以跨进程和 AppDomains 使用。查看 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();
}
}

关于c# - 在 .net 中通过 ApplicationDomain 边界实现回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5666677/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com