how can i create new thread in the new appdomain ?

  • Thread starter Thread starter Jon Skeet
  • Start date Start date
J

Jon Skeet

[Quick comment - I know *I* would find it easier to read your posts if
you used full English words like "you" and "are" rather than "u" and
"r". I don't know if anyone else agrees with me, admittedly, but
technical newsgroups don't tend to use this style of writing, in my
experience.]

Daylor said:
in win32 process , when u create new process,u have new main thread.

i know,appDomain r logical procces,that exists in 1 win32 process.

It's not quite that simple. AppDomains are logically separate in terms
of the objects etc, but threads can traverse AppDomains.
the q:
is there way to create second appDomain (the first 1 is the defualt
appDomain) with his new ("main") thread ?

I don't believe .NET has any concept of the "main" thread. There are
foreground threads and background threads - that's all. (I could be
wrong though - and I'm sure COM affects things, with apartments etc.)
if not ,what is the easy and clear way to create new thread on the new
appDomain ?

You don't really create threads "on" an AppDomain. You just create
threads, and they run code.
 
in win32 process , when u create new process,u have new main thread.

i know,appDomain r logical procces,that exists in 1 win32 process.

the q:
is there way to create second appDomain (the first 1 is the defualt
appDomain) with his new ("main") thread ?

if not ,what is the easy and clear way to create new thread on the new
appDomain ?
 
About threads crossing application domains, you need to make a clear
distinction between hard threads (OS threads) and soft threads
(CLR threads) here.
While hard threads don't have application domain affinity (they are not
tied to a specific application domain), CLR threads do have
this affinity so they cannot cross AD. borders.

Willy.


The information that I have read indicates that CLR threads are not bounded
to a single appdomain. I agree that there is a distinction between OS
threads and CLR threads. A CLR thread is an object that is mapped to an OS
thread, that the mapping between a CLR thread and an OS thread can change,
and an OS thread can be mapped to different CLR thread objects at different
times. However, this is an implementation detail of the current version of
the CLR and may change in the future (e.g. if the CLR ever implements
threading on top of fibers instead of OS threads). I disagree that CLR
threads are bounded by AD borders.

Here is a direct quote from the documentation of the Thread class:
"GetHashCode provides identification for managed threads. For the lifetime
of your thread, it will not collide with the value from any other thread,
regardless of the application domain from which you obtain the value.
Note An operating-system ThreadId has no fixed relationship to a managed
thread, because an unmanaged host can control the relationship between
managed and unmanaged threads. Specifically, a sophisticated host can use
the CLR Hosting API to schedule many managed threads against the same
operating system thread, or to move a managed thread between different
operating system threads."

This clearly implies that the thread of execution can cross appdomain
boundaries. Now, it may be that the CLR thread object is bounded in the
sense that because it is not derived from MarshalByRefObj a direct reference
to that object cannot be passed to another appdomain (a copy of the object
such that a new copy that preserves the original identity would be used in
the other appdomain). However, this is not the same thing as the current
thread of execution.

These details are of interest to those of us that like to know what is going
on below the surface; managed code almost never needs to know about this.
From the perspective of an application a sequence of instructions is
executed on a logical thread and the logical thread can cross appdomain
boundaries and preserve its CLR identity.

If my understanding of this is incorrect then please provide more
information.

Dave
 
Dave wrote:
||| About threads crossing application domains, you need to make a clear
|| distinction between hard threads (OS threads) and soft threads
||| (CLR threads) here.
||| While hard threads don't have application domain affinity (they are
||| not
|| tied to a specific application domain), CLR threads do have
||| this affinity so they cannot cross AD. borders.
|||
||| Willy.
|||
||
||
|| The information that I have read indicates that CLR threads are not
|| bounded to a single appdomain. I agree that there is a distinction
|| between OS threads and CLR threads. A CLR thread is an object that
|| is mapped to an OS thread, that the mapping between a CLR thread and
|| an OS thread can change, and an OS thread can be mapped to different
|| CLR thread objects at different times. However, this is an
|| implementation detail of the current version of the CLR and may
|| change in the future (e.g. if the CLR ever implements threading on
|| top of fibers instead of OS threads). I disagree that CLR threads
|| are bounded by AD borders.
||
|| Here is a direct quote from the documentation of the Thread class:
|| "GetHashCode provides identification for managed threads. For the
|| lifetime of your thread, it will not collide with the value from any
|| other thread, regardless of the application domain from which you
|| obtain the value. Note An operating-system ThreadId has no fixed
|| relationship to a managed thread, because an unmanaged host can
|| control the relationship between managed and unmanaged threads.
|| Specifically, a sophisticated host can use the CLR Hosting API to
|| schedule many managed threads against the same operating system
|| thread, or to move a managed thread between different operating
|| system threads."
||
|| This clearly implies that the thread of execution can cross appdomain
|| boundaries. Now, it may be that the CLR thread object is bounded in
|| the sense that because it is not derived from MarshalByRefObj a
|| direct reference to that object cannot be passed to another
|| appdomain (a copy of the object such that a new copy that preserves
|| the original identity would be used in the other appdomain).
|| However, this is not the same thing as the current thread of
|| execution.
||
|| These details are of interest to those of us that like to know what
|| is going on below the surface; managed code almost never needs to
|| know about this. From the perspective of an application a sequence
|| of instructions is executed on a logical thread and the logical
|| thread can cross appdomain boundaries and preserve its CLR identity.
||
|| If my understanding of this is incorrect then please provide more
|| information.
||
|| Dave


In order for an class instance to be agile(allowed to flow between AD's) it must not (amongst other rules) refer to instances that
are not agile, this is clearly not the case for the Thread class who refers to managed thread local storage (TLS). However each
managed threads can freely call into a remote application domain and they must do this as quickly as possible therefore they are
treated very carefully by the CLR.
When a managed thread calls into another AD and the target calls Thread.CurrentThread the CLR will bleed certain Thread properties
like Hashcode, Name, Priority etc. without using a marshaller (MSFT calls this Marshall by bleeding, in fact the target gets a
reference to the original Thread object but access is controlled by the CLR), other properties like the soft thread TLS however
remain AD bound.

Willy.
 
In order for an class instance to be agile(allowed to flow between AD's)
it must not (amongst other rules) refer to > instances that are not agile,
this is clearly not the case for the Thread class who refers to managed
thread local
storage (TLS).

After I wrote the previous message my memory was tickled by something along
these lines I had read on Chris Brumme's blog. I was incorrect about the
Thread object being marshalled by value; it is indeed marshalled by bleed.
However, my main point remains unchanged. Here's a quote from Chris... "In
other cases, we absolutely require that an instance marshal by bleed.
System.Threading.Thread is a good example of this. The same managed thread
can freely call between AppDomains. Since the current marshaler cannot
guarantee that an instance will always bleed, we have made Thread
unmarshalable by the marshaler for now. Then the CLR bleeds it without
using the marshaler when you call Thread.CurrentThread"
....
"An agile instance must necessarily be of a type we loaded as
domain-neutral. However, the converse is not true. The vast majority of
domain-neutral types do not have agile instances.


If an instance marshals-by-bleed or if it performs identity-preserving
marshal-by-value, then by definition it is agile. The effect is the same in
both cases: it's possible to have direct references to the same instance
from multiple AppDomains"


This contradicts your statement - he states that a thread object is
marshalled-by-bleed and is agile.
However each managed threads can freely call into a remote application
domain and they must do this as quickly >as possible therefore they are
treated very carefully by the CLR. When a managed thread calls into
another AD and >the target calls Thread.CurrentThread the CLR will bleed
certain Thread properties like Hashcode, Name, Priority >etc. without using
a marshaller (MSFT calls this Marshall by bleeding, in fact the target gets
a reference to the >original Thread object but access is controlled by the
CLR), other properties like the soft thread TLS however
remain AD bound.

I still don't agree that a managed thread is bounded by an appdomain. I
agree that there are some components of the thread object that are AD bound,
but this does not mean that the thread itself is AD bound, only that some of
the thread's state must be partitioned by appdomain. An example of this are
statics, which can be per-AD, per-thread, per-Context or per-process.


Further, a thread is a repository for a great deal of information that go
far beyond managed properties such as hashcodes and names. The most
important of these is the stack. The stack must record all sorts of things,
such as exception records, appdomain transitions, and execution engine
frames (e.g. ContextTransition, Exception, PInvokeCall, etc). A thread may
wander between AppDomains, managed and unmanged code, etc., and all these
transitions are recorded on the stack. The execution engine needs to track
these for purposes such as updating stack-stored object references for the
GC, hold state for security checks, recognize transitions between AD and
managed/unmanaged code, finding handlers for stack unwinding during an
exception, etc.

It may be theoretically possible to build an execution engine that keeps
threads bounded to a single appdomain yet maintains a consistent state
across multiple appdomains, but I don't believe that is the way it was
implemented. Stack-walking would be incredibly inefficient (and error-prone)
if it had to access multiple thread objects. It would be far simpler to have
a single managed thread object that tracked all this information, and then
created objects per-instance, or allowed the CLR to control access to, those
fields that need to remain bounded to an AD.

Dave
 
Back
Top