The CLR
type system supports both virtual and non-virtual instance methods. And IL can contain both CALLVIRT and
CALL instructions. So it makes
sense that IL generators would call virtual methods using CALLVIRT and call
non-virtual instance methods...

Managed
strings are subject to ‘interning’.
This is the process where the system notices that the same string is used
in several places, so it can fold all the references to the same unique
instance.
Interning happens two ways in the CLR.
...

It’s not
possible to state exactly when a managed object will be collected. The garbage collector schedules itself
based on various heuristics. Even
if a garbage collection occurs, it may only collect the younger generations of
the heap. And the JIT...

What’s the
difference between WaitHandle.WaitOne/WaitAny/WaitAll and just PInvoke’ing to
WaitForSingleObject or WaitForMultipleObjects directly? Plenty.
There are
several reasons why we prefer you to use managed blocking through WaitHandle or ...

Developers
who are accustomed to the IDisposable pattern or to C#’s ‘using’ syntax
sometimes ask why COM Interop doesn’t support IDisposable on every Runtime
Callable Wrapper (RCW). That way,
managed code could indicate that it is finished using the...

Every so
often, someone tries to navigate from a managed System.Threading.Thread object
to the corresponding ThreadId used by the operating system.
System.Diagnostic.ProcessThread exposes the
Windows notion of threads. In other words, the OS threads...

A common question is how to initialize
code before it is called. In the
unmanaged world, this is done with a DLL_PROCESS_ATTACH notification to your
DllMain routine. Managed C++ can
actually use this same technique.
However, it has all the usual...

There are two kinds of
threads executing inside managed code: the ones we start in managed code
and the ones that wander into the CLR.
The ones that started in managed code include all calls to
Thread.Start(), the managed threadpool threads, and...

Developers
often wonder why they are forced to derive from MarshalByRefObject or
EnterpriseServices.ServicedComponent. It would be so much more convenient if they
could add a CustomAttribute to their class or use a marker interface to declare
that...

All managed objects other
than those derived from ServicedComponent, when exposed to COM, behave as if
they have aggregated the free threaded marshaler (FTM). In other words,
they can be called on any thread without any cross-apartment
marshaling...

Objects that
derive from MarshalByRefObject will marshal by reference rather than value.
Metaobjects like Assembly, Type and
MethodInfo do not derive from MarshalByRefObject. This is because we
don’t want Type to be marshal by ref, which implies...

There’s a subtle but important
difference between protected access in unmanaged C++ and protected access (i.e.
family) in the CLR. The difference is due to the CLR’s ability to build
security guarantees on top of type safety.
Imagine you had a...

One way you get this
exception is if unmanaged code does an OS RaiseException() or causes a
fault. If that exception is propagated up the stack to managed code, we
will try to map it to a managed exception. For example, STATUS_NO_MEMORY
maps to OutOfMemoryException...

We don't
expose the managed size of objects because we want to reserve the ability to
change the way we lay these things out.
For example, on some systems we might align and pack differently. For this to happen, you need to specify
tdAutoLayout for...

People often ask how
they can expose traditional DLL exports from managed assemblies.
Managed C++
makes it very easy to export functions. And you could use tricks like
ILDASM / ILASM to inject DLL exports into managed assemblies built with other...

If the operating system
schedules multiple threads against a hyper-threaded CPU, the CLR automatically
takes advantage of this. This is certainly the case for new versions of
the OS like Windows Server 2003.
Also, the
CLR did work to properly...

It is
not generally possible to turn off garbage collection. However, the garbage collector won’t run
unless “provoked.” Garbage collection
is triggered by:
1)
Allocation
2)
Explicit calls by the application to
System.GC.Collect
3)
Explicit...

#define BOOTUP_EXCEPTION_COMPLUS 0xC0020001
You may see
an exception with this code, or an HRESULT of this value, when trying to call
into managed code. This can happen
if you call in before the runtime has finished initializing, or after the ...

By
default, static fields are scoped to AppDomains. In other words, each AppDomain gets its
own copy of all the static fields for the types that are loaded into that
AppDomain. This is independent of
whether the code was loaded as domain-neutral or...