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.
Remoting and SocketsSocket Connection Limit Test Utility | ||||||||
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
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. |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This sample provides a custom RealProxy that can be used to guarantee
single-threaded access to arbitrary |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
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. |
Languages: | C# |
|
CLR Version: | 1.1 | |
Description: |
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. |
Languages: | C# |
|
CLR Version: | RC1 | |
Description: |
This sample demonstrates the 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. |
Languages: | C# VB.NET |
|
CLR Version: | RC1 | |
Description: |
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. |
Languages: | C#, VB.NET |
|
CLR Version: | 1.1, 2.0 | |
Description: |
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. Refer to the comments in |
Languages: | C# |
|
CLR Version: | Beta 2 | |
Description: |
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. |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
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. |
Languages: | C# |
|
CLR Version: | 1.0, 1.1 | |
Description: |
When server-side remoting components fire events (and when not using
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 The sample code below demonstrates the pattern a server-side piece of remoting code can use to take these precautions:
public class SomeServerClass : MarshalByRefObject { // _OnFoo holds list of registered clients for OnFoo event. // _eventLock is an object used to synchronize multithreaded // access to _OnFoo. A separate object is used because // (a) _OnFoo is initially null and (b) might change over time // as clients are registered and unregistered. // private EventHandler _OnFoo; private object _eventLock = new object(); // OnFoo - the publicly visible event. // public event EventHandler OnFoo { // The add/remove operations are performed while // holding the lock on the private _OnFoo field. // add { lock( _eventLock ) { _OnFoo += value; } } remove { lock( _eventLock ) { _OnFoo -= value; } } } public void SomeCodeThatFiresEvents() { EventHandler[] clients; // Grab the list of registered clients in a thread-safe // fashion by first acquiring the lock on the _eventLock // field (sychronizing with any calls to the OnFoo // add/remove handlers above). // lock( _eventLock ) { clients = _OnFoo.GetInvocationList(); } // Iterate through the list of clients, unregistering any that can // no longer be reached. // foreach( EventHandler client in clients ) { try { client(this, EventArgs.Empty); } catch { // Call our thread-safe OnFoo remove handler to // remove this client from the list of registered clients. // OnFoo -= client; } } } } 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. |
Languages: | C# |
|
CLR Version: | 1.0, 1.1 | |
Description: |
This source file defines a helper class called |
AppDomain BaseDirectory (APPBASE) Modification | ||||||||
Languages: | C# |
|
CLR Version: | 1.1 | |
Description: |
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:
AppDomainUpdater appDomainUpdater = new AppDomainUpdater(AppDomain.CurrentDomain); appDomainUpdater.BaseDirectory = @"c:\SomeOtherDirectory"; |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
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). Example usage: C:\Program Files\Microsoft Visual Studio .NET> asmstats . /r [progress messages omitted] Processed 581 assemblies comprising 581 modules. Types: 5,325 (of any kind) Classes: 3,182 (1,400 public) Attributes: 53 (13 public) Delegates: 486 (410 public) Interfaces: 1,124 (416 public) Enums: 372 (191 public) Value types: 108 (9 public) Members: 516,096 (of any kind, instance and static) Methods: 369,648 instance, 2,415 static Events: 29,253 instance, 10 static Properties: 62,764 instance, 94 static Fields: 16,429 instance, 35,483 static |
Languages: | C# |
|
CLR Version: | Beta 2 | |
Description: |
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 using System; class Point { private int x; private int y; public int XPos { get { return(x); } } public int YPos { get { return(y); } } public int Sum { return(x + y); } } class App { static void Main() { DynoIndexer di = new DynoIndexer(new Point(), true); di["x"] = 10; di["y"] = 20; Console.WriteLine("x = {0}", di["XPos"]); Console.WriteLine("y = {0}", di["YPos"]); Console.WriteLine("x + y = {0}", di["Sum"]); } } The above example uses the indexer to modify the The main intent of the |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This sample demonstrates how to use the Call-on-load processing has to be enabled with a single call to the static
|
Languages: | C# |
|
CLR Version: | Beta 2 | |
Description: |
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 c:\>sa mscorlib System.Collections.Hashtable System.Collections.Hashtable is serializable Implements ISerializable Implements IDeserializationCallback |
Languages: | C# |
|
CLR Version: | Beta 2 | |
Description: |
Utility that takes an assembly name and type name of an
attribute as input and prints out the c:\>au mscorlib Serializable Hierarchy: SerializableAttribute : Attribute Valid on: Class, Struct, Enum, Delegate AllowMultiple: False Inherited: False |
QueuedBackgroundWorker Component | ||||||||
Languages: | C# |
|
CLR Version: | CLR 2.0 | |
Description: |
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. |
Languages: | C# |
|
CLR Version: | CLR 2.0 | |
Description: |
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. |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This sample provides a custom implementation of a managed thread pool. The thread pool supports the following features: * Instrumented with numerous performance counters. * Can be explicitly started and stopped (and restarted). * ThreadPool class extends WaitHandle (pool is signalled when all threads exit after a Stop operation) * Configurable thread priority for threads. * Configurable foreground/background characteristic for threads. * Configurable thread base names. * Support for cancelling pending operations. * Configurable minimum thread count. * Configurable maximum thread count. * Configurable dynamic thread trigger. * Configurable dynamic thread decay. * Configurable limit to request queue size (default is unbounded). * Optional propogation of calling thread's call context. * Optional propogation of calling thread's security principal. * Optional propogation of calling thread's HTTP context. * Support for started/stopped event notification. |
Languages: | C# |
|
CLR Version: | 1.0, 1.1 | |
Description: |
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 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: CalcAndDisplaySumDelegate d = new CalcAndDisplaySumDelegate(someCalc.Add); d.BeginInvoke(2, 3, null);You would instead do this: CalcAndDisplaySumDelegate d = new CalcAndDisplaySumDelegate(someCalc.Add); AsyncHelper.FireAndForget(d, 2, 3); |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
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. |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This sample provides a custom RealProxy that can be used to guarantee
single-threaded access to arbitrary |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This file contains a class called 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. |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This sample demonstrates how to access and call the
|
Languages: | C# |
|
CLR Version: | Beta 2 | |
Description: |
This sample demonstrates the idiom used by many classes
in the framework (especially collection classes like
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 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: Foo f = Foo.Synchronized(new Foo()); // Use foo...Or optionally like this: Foo f = new Foo(); // Or retrieved from somewhere else... f = f.Synchronized(); // Use foo... |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This piece of sample code demonstrates using Two scenarios are described: using a |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This sample is an alternative demonstration of using |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
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). |
Parsing PE File Headers to Determine if a DLL or EXE is an Assembly | ||||||||
Languages: | C# |
|
CLR Version: | 1.1 | |
Description: |
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 I didn't particularly need this code, but a DevelopMentor colleague of mine did, so here it is. |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This sample defines and demonstrates the necessary Win32 and COM interop shims that allow an application to programmatically enumerate the contents of the global, download, and native assembly caches. |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This sample demonstrates how to use an application's configuration file
and This sample builds 4 versions of the same library assembly, and then deploys them to different subdirectories of the APPBASE along these lines: c:\...\sampledir app_1.0.0.0.exe app_1.2.3.4.exe app_2.0.0.0.exe app_3.0.0.0.exe \bin \1.0.0.0 testlib.dll \1.2.3.4 testlib.dll \2.0.0.0 testlib.dll \3.0.0.0 testlib.dllEach 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 |
Languages: | C# |
|
CLR Version: | Beta 2 | |
Description: |
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. |
Digital Signature Generation | ||||||||
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
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. |
Languages: | C# VB.NET |
|
CLR Version: | Beta 2 | |
Description: |
Demonstrates the use of the |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
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. |
Arbitrary Configuration File Parser | ||||||||
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This sample contains a class called |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This sample contains a class called The usage model is that, for example, an assembly named If you know the keys you're after, the following access syntax is probably the most convenient: AssemblySettings settings = new AssemblySettings(); string someSetting1 = settings["someKey1"]; string someSetting2 = settings["someKey2"];If you want to enumerate over the settings (or just as an alternative approach), you can do this too: IDictionary settings = AssemblySettings.GetConfig(); foreach( DictionaryEntry entry in settings ) { // Use entry.Key or entry.Value as desired... }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 |
Languages: | C# |
|
CLR Version: | Beta 2 | |
Description: |
Illustrates how to register additional Trace listeners using an application configuration file. |
Languages: | C# |
|
CLR Version: | Beta 2 | |
Description: |
This program demonstrates how to write and use a custom configuration section
handler to parse user-defined sections of application configuration files
(like <myStuff> <day>Wednesday</day> <hour>11</hour> <author> <fname>Mike</fname> <lname>Woodring</lname> <stats> <age>19</age> <sex>male</sex> </stats> <otherStuff> <color>red</color> <yetMoreStuff> <fuzzy>true</fuzzy> <round>false</round> </yetMoreStuff> </otherStuff> </author> </myStuff>
Once the IDictionary myStuff = (IDictionary) ConfigurationSettings.GetConfig("myStuff");The following would then retrieve the nested author information:
IDictionary authorInfo = (IDictionary)myStuff["author"]And the following would retrieve the nested stats information:
IDictionary status = (IDictionary)authorInfo["stats"] |
Using Custom Context Attributes to Build Interception-Based Services | ||||||||
Languages: | C# |
|
CLR Version: | 1.0, 1.1 | |
Description: |
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 (
For example, the following class requests that all strings passed to the
[StringServices] public class Foo : ContextBoundObject { [InvertStringCase] private string _baz = "Foo Bar"; [ReverseStrings] public void Bar( string s1, int x, string s2 ) { } } 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.
Gratuitous search terms: |
Languages: | C# |
|
CLR Version: | Beta 2 | |
Description: |
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). |
Languages: | C# |
|
CLR Version: | Beta 2 | |
Description: |
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. |
TinyURL Utility | ||||||||
Languages: | C# |
|
CLR Version: | 1.1 | |
Description: |
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! |
Languages: | C# |
|
CLR Version: | 1.0, 1.1 | |
Description: |
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. You can checkout Richard's version here: |
Languages: | C# VB.NET |
|
CLR Version: | V1 | |
Description: |
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. |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This sample defines and uses several COM interop shims in C#
for accessing the unmanaged |
Languages: | C# |
|
CLR Version: | Beta 2 | |
Description: |
Demonstrates the use of |
Languages: | C# |
|
CLR Version: | RC1 | |
Description: |
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. |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
This library provides a sample implementation of |
Languages: | C# |
|
CLR Version: | V1 | |
Description: |
Sample code that provides a |