views:

145

answers:

2

Hi,

I'm creating an Appdomain to run a piece of code that can literally be any thing. I want my host process to be able when all the word is complete but async calls/threads are blocking my efforts. My code is something like this:

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

mbro.Run();

And work unit does an async call like this:

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

What I'm looking for is for a way to know when everything is done. I'm not sure how but I found the other day that if you used that WorkUnit inside a ASPX page it wouldn't finish the request until the async webclient call is complete. Point being, its possible but I dunno how.

A: 

I'm not familiar with the WorkUnit class, but if you find the thread in which it runs you could use Thread.Join. I'm not sure this answers your question... but perhaps gives you a pointer in the right direction.

Nestor
I've tried that.Thread t = new Thread(new ThreadStart(wu.Run));t.Start(); t.Join();And it simply keeps running (doesn't stop on the Join).
Alexandre Gomes
This is because your DownloadStringAsync call uses another thread to do the download. As you have already created a new thread you could just use the synchronous call for downloading it.
Matt
A: 

if I'm understanding your question correctly you want the main thread to block until async call would finish. In this case I would recommend to use an event object and signal it at the DownloadStringCompleted method of your WorkUnit class. Here's your code slightly modified:

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

hope this will give you an idea on how to proceed with your task

serge_gubenko
Hi, this is not it because the WorkUnit is out of my control. It could be an Addin or even an ASP.Net page. Basically I need to be able to correctly Unload the appdomain after the task is completed avoiding, if possible, to force the WorkUnit to signal that. The reason I'm avoiding that is because a simple bug could hang the AppDomain until some timeout occured.
Alexandre Gomes
I'd say that you have to then assume that if control returns from the Run method then the work unit has finished it's work and leave it up to the implementers of the work units to ensure that they wait for their async calls to complete. This is how the BCL threads work, the thread is finished when execution leaves the threadstart delegate.
Matt
Do you have any idea would does ASP.Net manages this kind of thing? I'm starting to think that using Processes instead of AppDomains would be better. The objective here is to give the most possible control and easy to use experience to the implementer of the WorkUnit.
Alexandre Gomes