2009-11-10 76 views
0

我正在創建一個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,它將不會完成請求,直到異步webclient調用完成。點是,它可能但我不知道如何。

回答

0

如果我正確理解你的問題,你希望主線程阻塞,直到異步調用完成。在這種情況下,我會建議使用事件對象,並在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(); 
    } 
} 

希望這會給你如何與你的任務

+0

嗨,這不是因爲WorkUnit超出了我的控制範圍。它可能是一個Addin,甚至是一個ASP.Net頁面。基本上我需要能夠在任務完成後正確卸載appdomain,以避免在可能的情況下強制WorkUnit發出信號。我避免這個原因是因爲一個簡單的bug可能會掛起AppDomain,直到發生某種超時。 – 2009-11-10 03:14:43

+0

我想說,你必須假設,如果控制從Run方法返回,那麼工作單元已經完成了工作,並將其留給工作單元的實現者,以確保他們等待他們的異步調用完成。這就是BCL線程的工作方式,線程在執行離開threadstart委託時完成。 – Matt 2009-11-10 04:09:30

+0

你有什麼想法會ASP.Net管理這種事情嗎?我開始認爲使用Processes而不是AppDomains會更好。這裏的目標是爲WorkUnit的實施者提供最可能的控制和易用的體驗。 – 2009-11-10 04:13:14

0

我對WorkUnit類不熟悉,但是如果找到它運行的線程,則可以使用Thread.Join。我不確定這是否會回答你的問題......但也許會給你一個正確的方向。

+0

我已經試過了前進的想法。 線程t =新線程(new ThreadStart(wu.Run)); t.Start(); t.Join(); 它只是繼續運行(不會停止加入)。 – 2009-11-10 00:41:19

+0

這是因爲您的DownloadStringAsync調用使用另一個線程來執行下載。由於您已經創建了一個新線程,因此您可以使用同步呼叫下載它。 – Matt 2009-11-10 04:03:17