|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Question on AppDomain and ThreadWhen you create a new AppDomain, objects you created in there using say AppDomain.CreateInstanctAndUnwrap() run in the same thread as the caller is that correct? If so, how could I create an AppDomain having its distinct thread? In particularly, I would like to create several AppDomains each with its own STA so that I can have UI object living in them and they are running concurrently. Kind of like transplanting an unmanaged architecture involving several ole automation servers (executables with their independent threads) to managed world using one executables but they are mapped to AppDomain partitioning. But each AppDomain must have its own thread with its own message pump so that WinForm objects can live there. Thanks. Leon Hi Leon,
> When you create a new AppDomain, objects you created in there using say When you invoke a method on the object it will be invoked on the current > AppDomain.CreateInstanctAndUnwrap() run in the same thread as the caller > is > that correct? thread in the AppDomain in which the object was created. > If so, how could I create an AppDomain having its distinct thread? In AppDomains don't own threads. They are shared amongst all AppDomains in the > particularly, I would like to create several AppDomains each with its own > STA > so that I can have UI object living in them and they are running > concurrently. process, but a single thread will only execute in one AppDomain at a time. To execute code concurrently and within a different AppDomain, create a background thread to invoke an object's method or provide asynchronous methods on your object (preferred). If the object is a MarshalByRefObject obtained from a different AppDomain then the code will execute within that AppDomain, concurrently with the main thread of your application, when calling on a background thread just as it would an object within the same AppDomain as the caller. > Kind of like transplanting an unmanaged architecture involving several ole I'm not sure what value there would be in managing multiple interface > automation servers (executables with their independent threads) to managed > world using one executables but they are mapped to AppDomain partitioning. > But each AppDomain must have its own thread with its own message pump so > that > WinForm objects can live there. components in multiple AppDomains, but I don't think it's possible anyway. Controls can only be manipulate on the thread in which they were created. Therefore, you may be able to have Forms within different AppDomains running simultaneously, but I doubt that you'll be able to make them children of the same MDI container, and you won't be able to have controls from different AppDomains on the same Form. If you were intending to do drag & drop operations between different Forms, for example, that wouldn't work either unless the control was recreated in the target AppDomain's thread. Normally, an application has just one GUI thread and invokes long-running processes on background threads. If the long-running processes need isolation from the default AppDomain then you can execute them within a separate AppDomain, asynchronously, but all GUI components should be created on the same thread (the one that started the message loop with a call to Application.Run). -- Dave Sexton Dave Sexton wrote:
> I'm not sure what value there would be in managing multiple interface Probably mostly memory consumption. Running multiple apps in separate> components in multiple AppDomains, AppDomains of a single process means that they share all the CLR machinery, not just its code pages; they share a single garbage-collected heap; they share a single string interning table; there's only one set of metadata loaded for each common library; there's none of the OS overhead involved in creating and running multiple processes. Secondarily, startup time might be lower for the 'other' apps, as much of their code will already be loaded. Hi Jon,
Thanks for your reply. You make an interesting point, but there is an added overhead of having to marshal calls between the AppDomains through a transparent proxy that uses the remoting framework's messaging system. I'm not sure it's worth it if the OP will be invoking methods across AppDomain boundaries. There seems to be a trade-off between memory consumption and performance here that the OP would have to make, considering also that there is no requirement to aggregate the GUI components from multiple threads into a single GUI, which is not possible in WinForms. -- Show quoteDave Sexton "Jon Shemitz" <j**@midnightbeach.com> wrote in message news:4569E908.CA063276@midnightbeach.com... > Dave Sexton wrote: > >> I'm not sure what value there would be in managing multiple interface >> components in multiple AppDomains, > > Probably mostly memory consumption. Running multiple apps in separate > AppDomains of a single process means that they share all the CLR > machinery, not just its code pages; they share a single > garbage-collected heap; they share a single string interning table; > there's only one set of metadata loaded for each common library; > there's none of the OS overhead involved in creating and running > multiple processes. > > Secondarily, startup time might be lower for the 'other' apps, as much > of their code will already be loaded. > > -- > > .NET 2.0 for Delphi Programmers > www.midnightbeach.com/.net > What you need to know. Thanks Dave for your reply. My comments below.
"Dave Sexton" wrote: <snip>Show quote > I'm not sure what value there would be in managing multiple interface I probably did not make it very clear. Objects in this AppDomain, > components in multiple AppDomains, but I don't think it's possible anyway. > Controls can only be manipulate on the thread in which they were created. > Therefore, you may be able to have Forms within different AppDomains running > simultaneously, but I doubt that you'll be able to make them children of the > same MDI container, and you won't be able to have controls from different > AppDomains on the same Form. If you were intending to do drag & drop > operations between different Forms, for example, that wouldn't work either > unless the control was recreated in the target AppDomain's thread. > > Normally, an application has just one GUI thread and invokes long-running > processes on background threads. If the long-running processes need > isolation from the default AppDomain then you can execute them within a > separate AppDomain, asynchronously, but all GUI components should be created > on the same thread (the one that started the message loop with a call to > Application.Run). particularly UI objects like controls are not required to marshal across the AppDomain boundary. While crossing AppDomain WinForm operation is problematics, it is not forebidden nor not possible. It only means you cannot marshal Control-derived objects across. Because these AppDomain contains essentially autonomous 'program-let', they can run by themselves. All they need to survive is a message pump and STA. Putting these 'program-let' in its AppDomain without its own thread prevents the manager (aka Windows Explorer) from terminating them should they become stuck. Drag-Drop is not considered. One possible way to give each AppDomain its own STA Thread is to have a client side component that manages this AppDomain's lifetime as well as its thread. My idea is then to create this AppDomain in a thread's ThreadStart (the thread proc). Since this component starts the Thread, it can define the ApartmentState prior to starting the thread. However, I am at a loss of how to maintain a message loop inside this thread proc (in managed code) to dispatch messages for windows objects created in this thread. In unmanaged world, this is simply a MsgWaitForMultipleObjects() or GetMessage() followed by TranslateMessage/DispatchMessage(). In the Main, one has Application.Run() while is essentially the unmanaged world's GetMessage() loop. How do you do similar thing in .Net/Managed code? Transplanting a design involving multiple applications into multi-AppDomains has many benefits as some other readers have commented. One particularly one is that .Net BCL does not have application lifecycle management framework that COM has. Using .Net Remoting often is a struggle with starting and terminating server in this usage as .Net Remoting assumes the server is already running and never die. Leon Hi Leon,
<snip> > However, I am at a loss of how to maintain a message loop inside this I tried creating a test program that called Application.Run on two separate > thread > proc (in managed code) to dispatch messages for windows objects created in > this thread. In unmanaged world, this is simply a > MsgWaitForMultipleObjects() > or GetMessage() followed by TranslateMessage/DispatchMessage(). > > In the Main, one has Application.Run() while is essentially the unmanaged > world's GetMessage() loop. > > How do you do similar thing in .Net/Managed code? threads, concurrently, each executing in separate AppDomains and both startup Forms were visible and interactive. The Application.MessageLoop property returned true in both threads. 1. Define a class that derives from MarshalByRefObject 2. Add a method such as the following: public EventWaitHandle RunAsync() { EventWaitHandle closedEvent = new EventWaitHandle(false, EventResetMode.AutoReset); Thread thread = new Thread(delegate() // 2.0 anonymous method { // the following line will block until Form is closed System.Windows.Forms.Application.Run(new Form()); closedEvent.Set(); }); thread .SetApartmentState(ApartmentState.STA); thread .Start(); return closedEvent; } 3. When your application starts create a new AppDomain 4. Create a new instance of your MarshalByRefObject in the new AppDomain by calling CreateInstanceAndUnwrap 5. Call the RunAsync method. > Transplanting a design involving multiple applications into When calling between AppDomains you're still using the remoting framework, > multi-AppDomains > has many benefits as some other readers have commented. One particularly > one > is that .Net BCL does not have application lifecycle management framework > that COM has. Using .Net Remoting often is a struggle with starting and > terminating server in this usage as .Net Remoting assumes the server is > already running and never die. however, so the same assumptions are still made. An AppDomainUnloadedException is thrown in the case that a proxy becomes unusable because the AppDomain in which its target was created has been unloaded, although that's much better, IMO, than the generic RemotingException that would be thrown in a similar, cross-process circumstance. -- Dave Sexton Thanks Dave for that great suggestion.
<snip> > When calling between AppDomains you're still using the remoting framework, I am at a loss to understand what you mean here? I realise crossing > however, so the same assumptions are still made. An > AppDomainUnloadedException is thrown in the case that a proxy becomes > unusable because the AppDomain in which its target was created has been > unloaded, although that's much better, IMO, than the generic > RemotingException that would be thrown in a similar, cross-process > circumstance. AppDomain would involve the remoting framework. That's fine because there is extremely little traffic crossing that AppDomain and I can bear with that. When did you get the AppDomainUnloadedException? Is that when you unload the AppDomain while the forms are still running? Thanks again. Hi Leon,
An AppDomainUnloadedException will be thrown when code attempts an invocation on a proxy that is no longer valid because the AppDomain in which its target was created has been unloaded. e.g., create and unwrap a MarshalByRefObject from another AppDomain, creating a transparent proxy in the calling AppDomain, then unload the AppDomain in which the proxy's target was created and try to invoke a method. The point is that a cross-process call, where the proxy is no longer valid, results in a RemotingException (for Ipc, SocketException for Tcp or WebException for Http), which is quite ambiguous. AppDomainUnloadedException, to the contrary, is quite clear. -- Show quoteDave Sexton "Leon" <newsgroup01.3.mailcenter***@neverbox.com> wrote in message news:E0FA95AA-7BA8-43A5-A780-AB6ED497C90E@microsoft.com... > Thanks Dave for that great suggestion. > > <snip> > >> When calling between AppDomains you're still using the remoting >> framework, >> however, so the same assumptions are still made. An >> AppDomainUnloadedException is thrown in the case that a proxy becomes >> unusable because the AppDomain in which its target was created has been >> unloaded, although that's much better, IMO, than the generic >> RemotingException that would be thrown in a similar, cross-process >> circumstance. > I am at a loss to understand what you mean here? I realise crossing > AppDomain would involve the remoting framework. That's fine because there > is > extremely little traffic crossing that AppDomain and I can bear with that. > > When did you get the AppDomainUnloadedException? Is that when you unload > the > AppDomain while the forms are still running? > > Thanks again.
Show quote
"Dave Sexton" wrote: So as long as I am aware that the AppDomain is unloaded and to clean out the > Hi Leon, > > An AppDomainUnloadedException will be thrown when code attempts an > invocation on a proxy that is no longer valid because the AppDomain in which > its target was created has been unloaded. e.g., create and unwrap a > MarshalByRefObject from another AppDomain, creating a transparent proxy in > the calling AppDomain, then unload the AppDomain in which the proxy's target > was created and try to invoke a method. > > The point is that a cross-process call, where the proxy is no longer valid, > results in a RemotingException (for Ipc, SocketException for Tcp or > WebException for Http), which is quite ambiguous. > AppDomainUnloadedException, to the contrary, is quite clear. proxy prior to unloading, I should be fine. Right. Leon Hi Leon,
Right :) -- Show quoteDave Sexton "Leon" <newsgroup01.3.mailcenter***@neverbox.com> wrote in message news:738A514A-2553-4D37-ABB2-5036BA915595@microsoft.com... > > > "Dave Sexton" wrote: > >> Hi Leon, >> >> An AppDomainUnloadedException will be thrown when code attempts an >> invocation on a proxy that is no longer valid because the AppDomain in >> which >> its target was created has been unloaded. e.g., create and unwrap a >> MarshalByRefObject from another AppDomain, creating a transparent proxy >> in >> the calling AppDomain, then unload the AppDomain in which the proxy's >> target >> was created and try to invoke a method. >> >> The point is that a cross-process call, where the proxy is no longer >> valid, >> results in a RemotingException (for Ipc, SocketException for Tcp or >> WebException for Http), which is quite ambiguous. >> AppDomainUnloadedException, to the contrary, is quite clear. > So as long as I am aware that the AppDomain is unloaded and to clean out > the > proxy prior to unloading, I should be fine. Right. > > Leon > Hi Leon,
Check out AppDomain.DoCallback() and documentation for the call and the CrossAppDomainDelegate . Haven't read through the discussion fully, but this may help. Don Box in Essential.NET advises that you use static methods for the callbacks themselves. Cordell Lawrence Teleios Systems Ltd. Show quote "Leon" <newsgroup01.3.mailcenter***@neverbox.com> wrote in message news:A07C4258-6677-4099-B40C-D4BA98138B6E@microsoft.com... > Hi, > > When you create a new AppDomain, objects you created in there using say > AppDomain.CreateInstanctAndUnwrap() run in the same thread as the caller > is > that correct? > > If so, how could I create an AppDomain having its distinct thread? In > particularly, I would like to create several AppDomains each with its own > STA > so that I can have UI object living in them and they are running > concurrently. > > Kind of like transplanting an unmanaged architecture involving several ole > automation servers (executables with their independent threads) to managed > world using one executables but they are mapped to AppDomain partitioning. > But each AppDomain must have its own thread with its own message pump so > that > WinForm objects can live there. > > Thanks. > > Leon |
|||||||||||||||||||||||