K
Keyee Hsu
Hi, I have a C# app that creates an AppDomain, enters it, and spawns an
asyn thread to do some work and then block itself. Upon the completion
of the work, the async thread supposedly terminates, then the original
thread unblocks, unloads the AppDomain, and starts the whole process all
over again. I get the System.AppDomainUnloadedException saying that the
AppDomain from which the async thread resides has been unloaded. Now,
if I were to add a Thread.Sleep() command before the main thread returns
and unloads the AppDomain, then everything ran fine. I include the
program below hoping someone would shed some lights on this.
Thanks!
// program begins....
using System;
using System.Reflection;
using System.Threading;
namespace adSample
{
delegate void appDomainDelegate();
class asyncAD: MarshalByRefObject
{
private static AutoResetEvent evtWorkDone = new
AutoResetEvent(false);
[STAThread]
static void Main(string[] args)
{
try
{
for (int ix=0; ix<5; ++ix)
{
AppDomain AD =
AppDomain.CreateDomain("monitorAppDomain", null, null);
asyncAD ad = (asyncAD)AD.CreateInstanceAndUnwrap
(
Assembly.GetCallingAssembly().FullName,
"adSample.asyncAD"
);
ad.wrkStart();
Console.WriteLine("unloading AD\r\n");
AppDomain.Unload(AD);
} // for()
}
catch (AppDomainUnloadedException ex)
{
Console.WriteLine( "caught: {0}", ex.Message );
}
Console.WriteLine("Press Enter to quit the sample\r\n");
Console.ReadLine();
} // Main
//
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public void wrkStart()
{
appDomainDelegate dlgtAD = new
appDomainDelegate(wrkSpinoff);
/*
// case 1 ==================> OK
IAsyncResult iAR = dlgtAD.BeginInvoke(null,
null);
while (!iAR.IsCompleted)
{
Thread.Sleep(100);
} // while()
// Call EndInvoke to retrieve the results.
dlgtAD.EndInvoke(iAR);
*/
/*
// case 2 ==================> OK
IAsyncResult iAR = dlgtAD.BeginInvoke(null,
null);
// Call EndInvoke to retrieve the results.
dlgtAD.EndInvoke(iAR);
Thread.Sleep(1000);
*/
/*
// case 3 ==================>
System.AppDomainUnloadedException
IAsyncResult iAR = dlgtAD.BeginInvoke(null,
null);
// Call EndInvoke to retrieve the results.
dlgtAD.EndInvoke(iAR);
*/
/*
// case 4 ==================> OK
IAsyncResult iAR = dlgtAD.BeginInvoke(new
AsyncCallback(wrkCallback),
dlgtAD);
evtWorkDone.WaitOne();
Thread.Sleep(1000);
*/
/*
*/
// case 5 ==================>
System.AppDomainUnloadedException
IAsyncResult iAR = dlgtAD.BeginInvoke(new
AsyncCallback(wrkCallback),
dlgtAD);
evtWorkDone.WaitOne();
Console.WriteLine("exiting from: {0}",
Thread.GetDomain().FriendlyName);
} // wrkStart()
//
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public void wrkSpinoff()
{
Console.WriteLine("in wrkSpinoff()");
for (int ix=0; ix<5; ++ix)
{
Console.WriteLine(ix);
Thread.Sleep(500);
} // for(ix)
Console.WriteLine("exiting wrkSpinoff()");
} // wrkSpinof()
//
-------------------------------------------------------------------
private void wrkCallback(IAsyncResult ar)
{
Console.WriteLine("in wrkCallback()");
appDomainDelegate dlgt = (appDomainDelegate)ar.AsyncState;
dlgt.EndInvoke(ar);
Console.WriteLine("exiting wrkCallback()");
evtWorkDone.Set();
} // wrkCallback()
} //asyncAD
} // adSample
asyn thread to do some work and then block itself. Upon the completion
of the work, the async thread supposedly terminates, then the original
thread unblocks, unloads the AppDomain, and starts the whole process all
over again. I get the System.AppDomainUnloadedException saying that the
AppDomain from which the async thread resides has been unloaded. Now,
if I were to add a Thread.Sleep() command before the main thread returns
and unloads the AppDomain, then everything ran fine. I include the
program below hoping someone would shed some lights on this.
Thanks!
// program begins....
using System;
using System.Reflection;
using System.Threading;
namespace adSample
{
delegate void appDomainDelegate();
class asyncAD: MarshalByRefObject
{
private static AutoResetEvent evtWorkDone = new
AutoResetEvent(false);
[STAThread]
static void Main(string[] args)
{
try
{
for (int ix=0; ix<5; ++ix)
{
AppDomain AD =
AppDomain.CreateDomain("monitorAppDomain", null, null);
asyncAD ad = (asyncAD)AD.CreateInstanceAndUnwrap
(
Assembly.GetCallingAssembly().FullName,
"adSample.asyncAD"
);
ad.wrkStart();
Console.WriteLine("unloading AD\r\n");
AppDomain.Unload(AD);
} // for()
}
catch (AppDomainUnloadedException ex)
{
Console.WriteLine( "caught: {0}", ex.Message );
}
Console.WriteLine("Press Enter to quit the sample\r\n");
Console.ReadLine();
} // Main
//
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public void wrkStart()
{
appDomainDelegate dlgtAD = new
appDomainDelegate(wrkSpinoff);
/*
// case 1 ==================> OK
IAsyncResult iAR = dlgtAD.BeginInvoke(null,
null);
while (!iAR.IsCompleted)
{
Thread.Sleep(100);
} // while()
// Call EndInvoke to retrieve the results.
dlgtAD.EndInvoke(iAR);
*/
/*
// case 2 ==================> OK
IAsyncResult iAR = dlgtAD.BeginInvoke(null,
null);
// Call EndInvoke to retrieve the results.
dlgtAD.EndInvoke(iAR);
Thread.Sleep(1000);
*/
/*
// case 3 ==================>
System.AppDomainUnloadedException
IAsyncResult iAR = dlgtAD.BeginInvoke(null,
null);
// Call EndInvoke to retrieve the results.
dlgtAD.EndInvoke(iAR);
*/
/*
// case 4 ==================> OK
IAsyncResult iAR = dlgtAD.BeginInvoke(new
AsyncCallback(wrkCallback),
dlgtAD);
evtWorkDone.WaitOne();
Thread.Sleep(1000);
*/
/*
*/
// case 5 ==================>
System.AppDomainUnloadedException
IAsyncResult iAR = dlgtAD.BeginInvoke(new
AsyncCallback(wrkCallback),
dlgtAD);
evtWorkDone.WaitOne();
Console.WriteLine("exiting from: {0}",
Thread.GetDomain().FriendlyName);
} // wrkStart()
//
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public void wrkSpinoff()
{
Console.WriteLine("in wrkSpinoff()");
for (int ix=0; ix<5; ++ix)
{
Console.WriteLine(ix);
Thread.Sleep(500);
} // for(ix)
Console.WriteLine("exiting wrkSpinoff()");
} // wrkSpinof()
//
-------------------------------------------------------------------
private void wrkCallback(IAsyncResult ar)
{
Console.WriteLine("in wrkCallback()");
appDomainDelegate dlgt = (appDomainDelegate)ar.AsyncState;
dlgt.EndInvoke(ar);
Console.WriteLine("exiting wrkCallback()");
evtWorkDone.Set();
} // wrkCallback()
} //asyncAD
} // adSample