等待 Appdomain 代码完成

Posted

技术标签:

【中文标题】等待 Appdomain 代码完成【英文标题】:Waiting for Appdomain code to finish 【发布时间】:2009-11-10 00:11:18 【问题描述】:

我正在创建一个 Appdomain 来运行一段实际上可以是任何东西的代码。我希望我的主机进程能够在所有单词都完成但异步调用/线程阻止我的工作时。我的代码是这样的:

AppDomain ad = AppDomain.CreateDomain(...);
WorkUnit mbro = (WorkUnit)ad.CreateInstanceAndUnwrap(...);

mbro.Run();

工作单元会像这样进行异步调用:

class WorkUnit 

public override void Run()

    WebClient wb = new WebClient();
    wb.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wb_DownloadStringCompleted);
    wb.DownloadStringAsync(new Uri("http://localhost/WhoTouches/ThreadSleep.aspx"));


void wb_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

    Console.WriteLine("job is done now");


我正在寻找一种方法来知道一切何时完成。我不知道怎么做,但前几天我发现,如果您在 ASPX 页面中使用该 WorkUnit,在异步 Web 客户端调用完成之前,它不会完成请求。重点是,这是可能的,但我不知道如何。

【问题讨论】:

【参考方案1】:

如果我正确理解您的问题,您希望主线程阻塞,直到异步调用完成。在这种情况下,我建议使用事件对象并在 WorkUnit 类的 DownloadStringCompleted 方法中发出信号。这是您的代码稍作修改:

public class WorkUnit : MarshalByRefObject

   private AutoResetEvent _event = new AutoResetEvent(false);

   public void Run()
   
     WebClient wb = new WebClient();
     wb.DownloadStringCompleted += new DownloadStringCompletedEventHandler(wb_DownloadStringCompleted);
     wb.DownloadStringAsync(new Uri("some uri"));

     Console.WriteLine("Waiting for download to comlete...");
     _event.WaitOne();
     Console.WriteLine("done");
   

   void wb_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
   
     Console.WriteLine("job is done now");
     _event.Set();
   
 

希望这能让您了解如何继续您的任务

【讨论】:

嗨,这不是因为 WorkUnit 不在我的控制范围内。它可能是一个插件,甚至是一个 ASP.Net 页面。基本上我需要能够在任务完成后正确卸载 appdomain,如果可能的话,避免强制 WorkUnit 发出信号。我避免这样做的原因是因为一个简单的错误可能会挂起 AppDomain 直到发生超时。 我会说你必须假设如果控制从 Run 方法返回,那么工作单元已经完成了它的工作,并将其留给工作单元的实现者以确保他们等待完成他们的异步调用。这就是 BCL 线程的工作方式,当执行离开 threadstart 委托时,线程就结束了。 您知道 ASP.Net 会管理这种事情吗?我开始认为使用 Processes 而不是 AppDomains 会更好。这里的目标是为 WorkUnit 的实施者提供尽可能多的控制和易于使用的体验。【参考方案2】:

我不熟悉 WorkUnit 类,但如果您找到运行它的线程,您可以使用 Thread.Join。我不确定这是否能回答您的问题……但也许可以为您指明正确的方向。

【讨论】:

我试过了。线程 t = new Thread(new ThreadStart(wu.Run)); t.Start(); t.加入();它只是继续运行(不会在加入时停止)。 这是因为您的 DownloadStringAsync 调用使用另一个线程进行下载。由于您已经创建了一个新线程,您可以使用同步调用来下载它。

以上是关于等待 Appdomain 代码完成的主要内容,如果未能解决你的问题,请参考以下文章

为啥某些 .Net 程序集无法通过 AppDomain 的 GetAssemblies() 方法获得?

远程处理:从服务器 AppDomain 查找客户端 AppDomain / Assembly

AppDomain 等待异步任务防止 SerializationException

从字节数组加载时找不到 AppDomain 程序集

AppDomain 和 MarshalByRefObject 生命周期:如何避免 RemotingException?

是否可以避免将一些程序集加载到“AppDomain”中?