Mike Woodring's .NET Sample Page

This page contains sample code I've written to demonstrate various
things on the .NET platform. If you have specific questions about any of these
samples, you can email me at mike@bearcanyon.com.

If you have general questions about .NET that aren't specifically about
the code in my samples, please do not email me. Instead, search the archives of
DevelopMentor's public mailing lists.
Most of the topics on this page are discussed on the
DOTNET-CLR list.
And because numerous very sharp people participate on this
list, you're more likely to get a quick response to your question. Please just be sure to
check the archives first to avoid posting something that's been asked and answered already.

All of this code is provided as-is with no warranty as to its usefulness
or safety implied. Use at your own risk, etc., etc. That said, you're
free to use this source in your own production software, but you are not
permitted to redistributed the source code itself.

This utility consists of a client and server Windows Forms application that uses the
.NET socket classes to test the limits of a given machine's ability to accept or
make socket-based connections. Refer to the enclosed readme.htm file for more details.

This sample provides a custom RealProxy that can be used to guarantee
single-threaded access to arbitrary MarshalByRefObject-compatible
objects. The proxy can be dynamically 'wrapped' around existing
references to MarshalByRefObject-derived objects, or
installed automatically by applying the
provided ThreadSafeProxyAttribute attribute to any
ContextBoundObject-derived type.

This sample demonstrates how to write a custom channel sink (both client- and
server-side) that captures the client thread principal, transmits it, and
restores it on the server-side thread handling a remote method call.
This sink does not provide any extra measure of security - just extra
information. It's important to realize the vulnerabilities that are
possible using this kind of sink, so if you download this sample, be
sure to read the enclosed README.HTM file before using the code in a production
system.

This is the same sample as the Identity Remoting Channel Sink above, but tweaked to demonstrate
client-side configuration of the remoting channel and sinks programmatically instead of using
a configuration file.

This sample demonstrates the OneWayAttribute
remoting attribute. Specifically, it demonstrates how the
attribute does not affect intra-appdomain calls, but does
affect calls that go through message sinks.

To test:

o Unzip to a dir of your choice.
o Open a cmd shell in that dir.
o Use nmake to build.
o Execute "start server" to launch a server process.
o Execute "client" to run the client process.

This sample demonstrates using IIS/ASP.NET to host a CLR object
using .NET remoting. The sample uses both kinds of WellKnown
service types (singleton and singlecall) as well as a client-activated
type. This sample also demonstrates using the standard http channel/soap formatter
combination as well as the more compact, but still firewall friendly,
http channel/binary formatter combination.

This sample demonstrates the how to use events in a .NET remoting
scenario so that the server process does not need access to the
client assembly at run-time. Demonstrates the use of a shim
class for forwarding the delegate invocation used to fire the event.

Demo that uses the SOAP formatter to serialize an objref to disk,
which can then be transferred across the Internet using any
technology (MSN Messenger, email, etc), deserialized, and used
to make a method call back to the original object.

Unzip the source to a directory then build using nmake. Run the
exporter.exe on one machine, which will create soapobjref.txt.
Send that file to another person that also has the demo built.
Place that file in the directory where importer.exe resides, then
run importer. A message should be displayed on the server's console.

Contains a client and two versions of a string echo server.
One server can only handle one client at a time. The other
server demonstrates the use of asynchronous I/O in order to
handle multiple connected clients in an overlapped manner.

Firing Events from Remoting Servers

Languages:

C#

CLR Version:

1.0, 1.1

Description:

When server-side remoting components fire events (and when not using
[OneWay] decorated event delegates) they are making a
synchronous call to each registered client. If any of these clients
disconnects from the server without first unregistering, or is otherwise
unreachable, an exception will result in the server at the point where
the event is fired. Furthermore, iteration over the list of registered
clients will be terminated before the remaining clients can be notified
of the event.

If the thread that fires this event is one of your own threads, then your
thread will be terminated if not properly handled. But at least you'll
know you have a problem.

More typically, however, the thread that fires the event is not 'yours',
but rather a pooled thread that was used to process an incoming remote
method invocation, or maybe a timer tick event. In either case, the runtime
will have provided a top-level exception handler that either throws the
exception away (as with a timer) or marshals the exception back to the client
(as when a remote method invocation caused the event to fire). In the former
case, you may not even realize you have a problem, other than by virtue of the
fact that your timer-related functions cease. In the latter case, the poor
client that triggered the event firing will receive an exception as a result
of your failed attempt to fire the event.

No matter what the scenario may be, firing events from server-side code is
something that should be treated with great care. Luckily, it is fairly easy
to take proper defensive precautions - you just need to know how.

The basic idea is fairly simple - iterate over the list of registered clients,
calling each individually (using GetInvocationList). Catch any
exceptions that might result. If an exception occurs calling a particular
client, remove them from the list of registered clients. The only other dimension
is to do all of this in a thread-safe fashion so that your code to unregister
clients doesn't interfere with clients making remote method calls to your server
to do the same.

The sample code below demonstrates the pattern a server-side piece of remoting
code can use to take these precautions:

With the above pattern, if the callback to a given client fails for any
reason, the delegate referring to that client will be removed from the list
of registered clients. This has two effects: allowing the server-side code
to continue firing the event callback to clients that were registered after
the 'bad' client, and eliminating the needless timeout the next time this
event is fired by removing the offending client from the list.

This source file defines a helper class called RemotingConfigurationHelper
that provides methods for unregistering previously registered
client-activated and well-known service types (counterparts to
RemotingConfiguration.RegisterWellKnownServiceType and
RemotingConfiguration.RegisterActivatedServiceType).

This sample demonstrates how to modify This sample demonstrates how to modify an
existing AppDomain's BaseDirectory property so that assembly resolution can be
influenced on the fly. Using the class included in this sample, it looks
something like this:

This sample/utility demonstrates some very simple
use of reflection for compiling statistics on the types
contained in a given assembly, or all assemblies in a
given directory (optionally including all its subdirectories).

This sample provides a sample of using the reflection APIs
to get & set fields and properties, or invoke methods,
on an arbitrary object instance. The sample class
provided is called the DynoIndexer. The
DynoIndexer is used along these lines:

This sample demonstrates how to use the AppDomain.AssemblyLoad
event to hook assembly load notifications and, if the newly loaded assembly
has been annotated with one or more instances of the CallOnLoad
attribute, have one or more methods automatically invoked.

Call-on-load processing has to be enabled with a single call to the static
CallOnLoadAttribute.Enable method - no processing occurs until
this has been invoked in a given AppDomain. This method optionally allows
you to request that call-on-load processing be performed for assemblies that
have already been loaded into the AppDomain at the time Enable
has been called.

Utility that takes an assembly name and type name
as input and prints out an indication as to whether or
not the specified type is Serializable, and whether
or not the type implements the ISerializable interface
or the IDeserializationCallback interface.
Here's a sample of the output produced:

This sample program demonstrates a knock off of the System.ComponentModel.BackgroundWorker
class I call QueuedBackgroundWorker. Like BackgroundWorker, this component supports
a RunWorkerAsync method, and associated progress and completion methods and event notifications.
But unlike BackgroundWorker, this component supports overlapping calls to its RunWorkerAsync
method, allowing callers to queue up multiple operations for sequential execution by a background
thread.

The implementation of the QueuedBackgroundWorker component included in this sample
was written from the ground up so as to serve as an example of how to implement the
event-based asynchronous pattern
in your own components.

If you grab this code, be sure to read all of the comments at the top and bottom of
QueuedBackgroundWorker.cs and QueuedBackgroundWorkerWithoutAbusingConstructorInfo.cs
before using the QueuedBackgroundWorker component in your own code. The following entries
in my blog will provide additional information:
here,
here, and
here.

This sample program demonstrates one possible work around for the fact that the
RunWorkerCompletedEventArgs.UserState property always returns null, regardless of
how BackgroundWorker.RunWorkerAsync was called. The original write up on the
issue can be found in my blog.
This blog post provides the follow up and further explains this sample.
Refer to the comments through the source included with this sample for more details.

Starting with the 1.1 release of the .NET Framework, the SDK docs
now carry a caution that mandates calling EndInvoke on delegates
you've called BeginInvoke on in order to avoid potential leaks.
This means you cannot simply "fire-and-forget" a call to BeginInvoke
without the risk of running the risk of causing problems.

This sample provides an AsyncHelper class with one public method
called FireAndForget that is intended to support the fire-and-forget
idiom without the fear of leak. The usage model is that instead of calling
BeginInvoke against a delegate, you would instead call
AsyncHelper.FireAndForget, passing that delegate and it's parameters
as input.

For example, assuming a delegate defined as follows:

delegate void CalcAndDisplaySumDelegate( int a, int b );

Instead of doing this to fire-and-forget an async call to some
target method:

This is the C#/WinForms version of a CPU stress testing utility I wrote a few years
ago in C++/MFC. The utility provides a simple slider bar user interface that
allows you to place an arbitrary load on the processor(s) in
your system. Automatically detects and handles multiple processors.

This sample provides a custom RealProxy that can be used to guarantee
single-threaded access to arbitrary MarshalByRefObject-compatible
objects. The proxy can be dynamically 'wrapped' around existing
references to MarshalByRefObject-derived objects, or
installed automatically by applying the
provided ThreadSafeProxyAttribute attribute to any
ContextBoundObject-derived type.

This file contains a class called ThreadWaitHandle that is a derivative
of System.Threading.WaitHandle and that can be used to perform
WaitHandle.Wait* operations on thread objects. The purpose of the code
is to allow a programmer to create one or more threads and then, at some
later point, block until that thread exits.

Note - due to the nature of the implementation, this code is highly coupled
to the build of the CLR that the code was developed and tested on. Be sure
to read the comments in ThreadWaitHandle.cs for a more detailed explanation.

This sample demonstrates how to access and call the
ICorThreadpool interface that's implemented
in MSCOREE.DLL from a C# program in order to adjust
the operating constraints of the CLR-managed thread pool
for a given process. See the comments in tpcontrol.cs
and ICorThreadPool.cs for details.

This sample demonstrates the idiom used by many classes
in the framework (especially collection classes like
ArrayList) for supporting just-thread-safe-enough
access.

The general idea is that you don't want to make every class
thread-safe internally and therefore always pay the associated performance
penalty. Clients of your type that do not use your class in
a multithreaded environment will pay a price without gaining
any benefit. However, thread savvy programmers need a way
to use your object in a thread-safe fashion. In the absence
of any intrinsic support, clients can use the Monitor
class to acquire and release the SyncBlock associated with
your object instance. But most thread-aware classes provide
a thread-safe, type-compatible wrapper that takes care of the
thread-safety concerns internally. Such a wrapper is generally
exposed by calling a Synchronized method on the
object (or a static method on the type) that returns a new instance
of a nested type that does the lock acquisition and releasing.

By supporting this usage, programmers that use your type in a thread
safe environment can use your type directly as follows:

Foo f = new Foo();
// Use foo...

While programmers that use your type in a thread-hot environment can
use your thread-safe wrappers as follows:

This piece of sample code demonstrates using Control.BeginInvoke
to safely update WinForm controls from threads other than
the thread that the control was created on.

Two scenarios are described: using a Timer object
from the System.Threading namespace to periodically
update a control; and using Delegate.BeginInvoke to perform
some task asynchronously, and updating a control from the thread
that performs the specified callback.

This sample is an alternative demonstration of using Control.InvokeRequired
that demonstrates both the problem as well as the solution. In that regard, it's slighly
more educational than my other sample.

This little sample demonstrates the use of what I call a
"deferred procedure call (DPC) queue". The idea is similar
to using the built-in CLR thread pool for performing work
asynchronously to the thread issuing the request. However,
only one thread ever services the request queue, thus
ensuring the order of processing. In this way, you can use
multiple instances of a DPC queue to tackle different tasks
(potentially at a different priority).

This sample demonstrates how to parse the PE headers of any valid
Win32 Portable Executable (PE) file (DLL or EXE) to determine if that
file is in fact a .NET assembly (as opposed to just a vanilla Win32 PE file).
The technique I went with was to call the Win32 LoadLibraryEx
function with the DONT_RESOLVE_DLL_REFERENCES flag to map
the specified file into process memory. Then knowing that the HANDLE
returned by LoadLibraryEx is actually a pointer to the base
load address of the PE file in memory, I use C# pointer operations to
'walk through' the PE headers looking for a CLI header. As a result of
using pointer syntax, any assembly that uses this code must be built
to allow unsafe code blocks, which means it won't be verifiably type safe.
So keep that in mind if you decide to use this code.

I didn't particularly need this code, but a DevelopMentor colleague of mine
did, so here it is.

This sample demonstrates how to use an application's configuration file
and CODEBASE redirects to support the side-by-side installation
and loading of multiple versions of the same assembly without requiring
that the assemblies be installed into the GAC.

This sample builds 4 versions of the same library assembly, and then deploys
them to different subdirectories of the APPBASE along these lines:

Each application exe is built against the matching version of testlib.dll,
which is deployed to a different subdirectory below the APPBASE. Due to the CODEBASE
redirects in the application configuration file, running a particular
version of the application results in the desired version of testlib.dll being
loaded and used.

Refer to testlib.cs for instructions on how to build and
run this sample.

This sample demonstrates how to create and deploy publisher policy
for a strongly named assembly. The zip includes a readme.txt that
indicates how to move through the sample step-by-step in order to
see the effect of policy on assembly resolution at runtime.

This utility demonstrates the use of the SHA1Managed and
RSACryptoServiceProvider classes to generate, sign, and verify
signatures for arbitrary files. Useful when the data being
signed need not be encrypted, but any changes to the data need
to be detectable.

Someone once asked if there was a way to generate the public key token
for a given public key that's rendered in text form (for example, from an
ILDASM display). For what it's worth, this program does just that.

This sample contains a class called ConfigFileReader that
allows you to process the appSettings key/value settings
in arbitrary configuration files (not just the one that's automatically
parsed for the running application). The ConfigFileReader
class also allows you to process other key/value sections besides the
standard appSettings area.

This sample contains a class called AssemblySettings that
allows you to use per-assembly configuration files with appSettings-like
configuration elements.

The usage model is that, for example, an assembly named foo.dll located
in the c:\foo\bar\baz directory, a configuration file for that assembly
name foo.dll.config can be placed in the same directory and accessed
using the enclosed AssemblySettings class in the same fashion as
normal appSettings items can for application configuration files.

If you know the keys you're after, the following access syntax is probably
the most convenient:

In either of the above two scenarios, the calling assembly
(the one that called the constructor or GetConfig) is used
to determine what file to parse and what the name of the
settings collection element is. For example, if the calling
assembly is c:\foo\bar\baz\foo.dll, then the configuration file
that's parsed is c:\foo\bar\baz\Foo.dll.config, and the
configuration section that's parsed must be named <assemblySettings>.

To retrieve the configuration information for an arbitrary assembly,
use the overloaded constructor or GetConfig method that takes an
Assembly reference as input.

This program demonstrates how to write and use a custom configuration section
handler to parse user-defined sections of application configuration files
(like <appSettings>). The sample handler provided is
called the ElementNormalCfgHandler, and supports any element-normal
configuration section to an arbitrary depth. For example, this handler can
handle a section formatted as follows:

Once the ElementNormalCfgHandler assembly is registered in an
application configuration file, the application can retrieve the information
using ConfigurationSettings.GetConfig. Each element becomes
a key. Elements with a simple text child contain a text value associated
with that key. Elements with nested elements contain a dictionary value
associated with that key. For example, the following would retrieve the
root myStuff dictionary:

This sample demonstrates how to build a custom context attribute that installs
an interceptor which looks for attributes applied to the target object's
fields and methods to perform services. Two types of services are
supported: inverting the case of characters in strings and reversing the
character positions within strings. These services are requested by
applying one or both of two custom attributes (ReverseStrings and
InvertStringCase) to methods and/or fields of a type derived from
ContextObjectObject that has the StringServices context
attribute applied.

For example, the following class requests that all strings passed to the
Bar method be reversed when Bar is called, and
that the case of each character in the _baz field be inverted
whenever any method is called:

Performing such processing using the type information on methods is a simple matter
because each method call message passed to custom message sinks carries with it
the necessary type information. But processing fields on the target object requires
that the chain of message sinks leading from your custom message sink to the
eventual target object be traversed in order to locate the target object
whose method is being invoked. This sample demonstrates both techniques.

Like a few others, the first idea I had when I started exploring
the context architecture was to provide an automatic method
tracing facility. I haven't seen what others did, but this version
uses a dynamic sink approach, which lets you "wrap" and "unwrap"
the tracing facility around an object (or proxy to an object)
as needed at runtime. Exactly what's traced (process id, thread id,
context id, timestamp, etc.) is customizable via flags. Exactly where
the trace messages our output is pluggable - just pass pass any
Stream of your choosing when you install the interceptor (by default,
output goes to stdout).

The second idea I had when looking into the context infrastructure
was to be able to put an attribute on a class that caused some
performance counters to be automatically created and published that
could be monitored using PerfMon. This version is really crude,
but does demonstrate the feasibility (although non-deterministic
finalization makes things a little difficult in this case).
Applying the attribute to a class results in four counters being
published: Instance, Instances/sec, Calls, and Calls/sec. Counter
instances are named "ProcessId AppDomainName ClassName", so you can
monitor instances of the same type in different processes, or different
app domains within a process.

This little utility grabs a URL from the clipboard, sends it to tinyurl.com
to get/generate a tinyurl, and pastes the resulting tiny url back into the
clipboard. Configure a desktop shortcut to this utility to launch when
something like CTRL-SHIFT-T is pressed, and the entire long-to-tiny URL
converstion process is as easy as CTRL-C, CTRL-SHIFT-T, CTRL-V!

This sample demonstrates how to write a C# program that
supports "pluggable" native DLLs that conform to a required
C-based API of exported functions. Since p/invoke declarations
require compile-time knowledge of the DLL, they can't be used
in a more dynamic environment where you know the names and
signatures of the functions you want to call ahead of time,
but not which DLL you're going to load and call into. This
sample demonstrates how to work around p/invoke's limitations
to support this scenario.

Refer to the comments at the tops of the included source
code for more details.

Note, after working up this implementation, which I thought
was pretty clever, I went searching to to see if anyone else
had come up with this same solution. Sure enough,
Richard Birkby has (and 1.5 years ago at that). So much for
being original :-)

If you strip away everything in our code except
for the x86 assembly language and the core concept (so ignoring
the fluff of the surrounding test jigs we each wrote and the
fact that I used a __declspec(naked) function in C with inline
assembly, and he used the stand alone x86 assembler),
our solutions are identical.

Unlike VB.NET, C# does not support parameterized named properties (C# has
indexers instead, which are the default/unnamed paremeterized property
of a type). This sample demonstrates how to simulate parameterized
named properties in C# suitable for in any managed language, but specifically
for VB.NET clients that are accustomed to such a language feature.

This sample defines and uses several COM interop shims in C#
for accessing the unmanaged ICorPublishProcess,
ICorPublishAppDomain,
et. al. family of interfaces for enumerating (un)managed processes
and appdomains.

This sample demonstrates implementing IDataReader by taking a snapshot
of the list of running processes on an arbitrary machine and representing
the result via the IDataReader interface. I'm no data access pro, but
I wrote up this little sample to demonstrate how IDataReader can be used
to polymorphically represent arbitrary data in tabular form.