【问题标题】:Waiting for Appdomain code to finish等待 Appdomain 代码完成
【发布时间】: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 客户端调用完成之前,它不会完成请求。重点是,这是可能的,但我不知道如何。

【问题讨论】:

    标签: c# multithreading appdomain


    【解决方案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 调用使用另一个线程进行下载。由于您已经创建了一个新线程,您可以使用同步调用来下载它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-18
    • 2014-05-22
    • 1970-01-01
    • 2015-07-01
    • 2014-12-31
    • 2011-04-10
    • 2013-09-16
    相关资源
    最近更新 更多