Thursday, September 08, 2005

Testing

Testing

This is posted using blogger for word.

Let’s try some source code:


private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
      System.Diagnostics.Debug.WriteLine(e.KeyCode);
      System.Diagnostics.Debug.WriteLine(e.KeyData);
      System.Diagnostics.Debug.WriteLine(e.KeyValue);
      System.Diagnostics.Debug.WriteLine(e.Modifiers);
      if (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Return || e.KeyCode == Keys.A)
           e.Handled = true;
}


OK time to post

Hmm… not bad.  Lost the color on the keywords but I can live with that.

Saturday, November 06, 2004

Formatting code

Well I'm officially disappointed in blogger.

For the last couple of posts I've been trying to focus on some small classes or code snippets. Unfortunately I can't get the code to format in the way I want.

For regular text posts blogger is great. Its as easy as editing a document to create the look I want for my text. But I've tried editing my text in the compose window and as native html and bloogger still goes ahead and "fixes" my formatting.

I am going to search for a way to do this but I'm also looking for a new site to host my blog.


Monday, October 18, 2004

AsyncHelper - FireAndForget and FireAsync

When you want to call a method asynchronously you can have it execute on the ThreadPool very easily by creating a delegate and calling BeginInvoke on it:


void LongRunningOperation(int arg1, float arg2, object arg3)
{
//...
}

delegate void LongRunningOperationHandler(int arg1, float arg2, object arg3)
void RunLongRunningOperationAsynchronously(int arg1, float arg2, object arg3)
{
LongRunningOperationHandler handler = new LongRunningOperationHandler(LongRunningOperation);
handler.BeginInvoke(arg1, arg2, arg3, null, null);
}

Only thing is that the documentation as of the 1.1 version of the framework says that we must call EndInvoke on a delegate once we have called BeginInvoke or our application may leak.

The compiler generates the arguments for BeginInvoke and EndInvoke. BeginInvoke starts with all the in going and reference arguments. The last two arguments are common to all BeginInvoke methods. The second to last argument is an AsyncCallback delegate and the last argument is an the AsyncState, an object that we will be able to get back in the callback. BeginInvoke returns an object implementing the IAsyncResult:


public interface IAsyncResult
{
// Properties
object AsyncState { get; }
WaitHandle AsyncWaitHandle { get; }
bool CompletedSynchronously { get; }
bool IsCompleted { get; }
}


This same object is passed to the AsyncCallback handler.

To call the EndInvoke in the callback function we need to get access to the original delegate. One way to do this is pass it in as the AsyncState argument



void RunLongRunningOperationAsynchronously(int arg1, float arg2, object arg3)
{
LongRunningOperationHandler handler = new LongRunningOperationHandler(LongRunningOperation);
handler.BeginInvoke(arg1, arg2, arg3, new AsyncCallback(LongRunningOperationDone), handler);
}

void LongRunningOperationDone(IAsyncResult result)
{
LongRunningOperationHandler handler = result.AsyncState as LongRunningOperationHandler;
if (handler != null)
handler.EndInvoke(result);
}


The actual object implementing IAsyncResult is a System.Runtime.Remoting.Messaging.AsyncResult. IAsyncResult does not contain a property to get the original delegate but the AsyncResult has the AsyncDelegate property which we can use to get the delegate.



void RunLongRunningOperationAsynchronously(int arg1, float arg2, object arg3)
{
LongRunningOperationHandler handler = new LongRunningOperationHandler(LongRunningOperation);
handler.BeginInvoke(arg1, arg2, arg3, new AsyncCallback(LongRunningOperationDone), null);
}

void LongRunningOperationDone(IAsyncResult result)
{
AsyncResult resultObject = result as AsyncResult;
if (resultObject != null)
{
LongRunningOperationHandler handler = resultObject.AsyncDelegate as LongRunningOperationHandler;
if (handler != null)
handler.EndInvoke(result);
}
}



In many (most) cases I'm not interested in retrieving any results from the method. I use a class based on
Mike Woodring's method to call AsyncHelper.FireAndForget so that I don't have to bother with the EndInvoke.



// Based on AsyncHelper by Mike Woodring of http://staff.develop.com/woodring
//
// Use FireAndForget to execute a method in the thread pool without having to
// call EndInvoke. Note that the delegate passed to FireAndForget can only have a
// single Target.
// AsyncHelper.FireAndForget(new MyHandler(MyMethod), methodArg1, methodArg2, etc);
//
// To Fire an Event asynchronously (with each of the targets being called on its own thread
// use FireAsync:
// AsyncHelper.FireAsync(MyEvent, eventArg1, eventArg2, ...);
// FireAsync is designed to be called on an event containing zero, one or more Targets.
// Your FireEvent method does not need to check for null FireAsync will do it correctly even in a
// multithreaded environment
#region Using Statements
using System;
using System.Reflection;
using System.Threading;
using System.ComponentModel;
#endregion

namespace DanGo.Utilities
{
public class AsyncHelper
{
#region Private Types
// Private class holds data for a delegate to be run on the thread pool
private class Target
{
#region Private Fields
private readonly Delegate TargetDelegate;
private readonly object[] Args;
#endregion

#region Constructor
/// <summary>
/// Creates a new <see cref="Target"/> instance this holds arguments and contains
/// the method ExecuteDelegate to be called on the threadpool.
/// </summary>
/// <param name="d">The users delegate to fire</param>
/// <param name="args">The users arguments to the delegate</param>
public Target( Delegate d, object[] args)
{
TargetDelegate = d;
Args = args;
}
#endregion

#region Invoker
/// <summary>
/// Executes the delegate by calling DynamicInvoke.
/// </summary>
/// <param name="o">This parameter is required by the threadpool but is unused.</param>
public void ExecuteDelegate( object o )
{
TargetDelegate.DynamicInvoke(Args);
}
#endregion
}
#endregion

#region Public Static Methods
/// <summary>
/// Fires the delegate without any need to call EndInvoke.
/// </summary>
/// <param name="d">Target Delegate - must contain only one Target method</param>
/// <param name="args">Users arguments.</param>
public static void FireAndForget( Delegate d, params object[] args)
{
Target target = new Target(d, args);
ThreadPool.QueueUserWorkItem(new WaitCallback(target.ExecuteDelegate));
}

/// <summary>
/// Fires each of the members in the delegate asynchronously. All the members
/// will be fired even if one of them fires an exception
/// </summary>
/// <param name="del">The delegate we want to fire</param>
/// <param name="args">Each of the args we want to fire.</param>
public static void FireAsync(Delegate del, params object[] args)
{
// copy the delegate to ensure that we can test for null in a thread
// safe manner.
Delegate temp = del;
if(temp != null)
{
Delegate[] delegates = temp.GetInvocationList();
foreach(Delegate receiver in delegates)
{
FireAndForget(receiver, args);
}
}
}
#endregion
}
}


FireAndForget will only manage a delegate with a single handler. Often I want to fire events asynchronously. I do this with the AsyncHelper.FireAsync


Calling AsyncHelper.FireAsync has a number of advantages. Normally when we fire an event we don't know how long the clients will take to execute so that they can delay our processing. In addition if one clients handler throws an exception the following handlers will not get called.

Give AsyncHelper.FireAndForget and AsyncHelper.FireAsync a try!

Converting an Enum to its value...

Back in the presenters' room at Code Camp 2 I had an interesting conversation with Dave Mitchell of connectedbits.

He was creating a serialization library and having some trouble converting System.Enum to its underlying value. Sounds strange but you can't just cast it.

He has a method that wants to trat enums generically independent of the particular type of enum.


class Serializer
{
void Write(Enum enumValue)
{
}
}

He calls it with something like
serializer.Write(Color.Blue);
The code :
int val = (int)enumValue;
Does not compile.

The solution he is living with is:
int val =(int)Enum.Parse(enumValue.GetType(),enumValue.ToString());

I think I found him a better solution.

int GetEnumValue(Enum enumValue)
{
return (int)Convert.ChangeType(enumValue,val.GetTypeCode());
// Or
//return (int)Convert.ChangeType(enumValue,typeof(int));
}


But this ignores the fact that an enum can be a byte, sbyte, short, ushort, int, uint, long, or ulong.

So a more complete implementation might look something like this:

void Write(Enum enumValue)
{
TypeCode code = val.GetTypeCode();
object valueAsObject = Convert.ChangeType(enumValue, code);
switch(code)
{
case TypeCode.Byte :
Write((byte)valueAsObject);
break;
case TypeCode.SByte :
Write((sbyte)valueAsObject);
break;
case TypeCode.Int16 :
Write((short)valueAsObject);
break;
case TypeCode.UInt16 :
Write((ushort)valueAsObject);
break;
case TypeCode.Int32 :
Write((int)valueAsObject);
break;
case TypeCode.UInt32 :
Write((uint)valueAsObject);
break;
case TypeCode.Int64 :
Write((long)valueAsObject);
break;
case TypeCode.UInt64 :
Write((ulong)valueAsObject);
break;
}


Now we just supply overloaded Writes for each type and can write the correct underlying value.

Code Camp Complete

I gave my talk on Asynchronous Programming in .NET at code camp 2 today and it went pretty well. I only got half way through my slides so I can probably break it into two talks pretty easily.

A couple of old friends attended the lecture and it was great to see them.

If you were attending today and are looking for code I'll start to post it later this week.

I attended Richard Shaw's Generics lecture today and I began to work on a generic Cache class that I'll be blogging about. This was a good review of generics.

He suggested we all bone-up on Generic's and show up at Juval Lowy's lecture, C# 2.0 Generics on October 26 at the Microsoft Waltham office sponsored by http://beantowndotnet.org/.

He didn't suggest heckling just asking really tough questions.

I've never seen Juval Lowy before but I really like his book on Programming .NET components. It is well worth reading. His web-site has some very high quality test code available for download.

Saturday, October 16, 2004

The Emperor's Clothes: Code Camp II

I attended Code Camp II today.

This is a tremendous event there were 6 and 1/2 tracks. 2 web tracks, 2 smart client tracks, 1 and 1/2 mixed tracks and a datat & smart client track.

4 of the tracks were held in rooms holding 80 to 100 plus people but a couple of the tracks were in smaller rooms.

I started with Patrick Hynds talk on developing application under Windows XP SP2. This was a good talk that included how to configure the sp2 firewall programatically. This is important so that your install script can setup your application. For me the important info was that we must add our .NET remoting Server to the application whitelist. I'll be downloading his slide deck and studying it carefully.

Next I wanted to attend Jason Bock's talk but the room he was in was tiny and full. So I went to Robert Hurlbut's Chalk Talk on developing as a Non-Admin.

The argument for developing as non-admin is compelling but I'm afraid it still looked like a lot of trouble even given all the great tips he gave. I think I will give it a try. But I'm not sure I will stick with it.

But I did eek out a great idea. Robert was using RunAs to run with Amin Credentials. In this way he can temporarily run as admin to set ACL's or install code or debug.

My idea is to use RunAs to lower my crentials instead of increasing them. I'm going to try using RunAs to run NUNIT with regular user permissions. At least this may catch some problems in my components.

For session 3 I hit Richard Hale Shaw's talk on Patterns in C# programming I followed this up with his chalk talk on Pattern Mining with .NET. Richard's talks were the highlight of the day. He has developed a practical approach to identifying best-practices and patterns in .NET. The chalk-talk was especially interesting as we were able to identify some new patterns and help each other by finding some best-practices/patterns to resolve some problems.

I decided to try to see some other speakers even though I was enjoying Richard Shaw's talks so I attended Andy Novick's talk on "Building on the .NET Framework: Create Professional WinForms Applications". Sorry Andy but this was the weakest lecture of the day. Andy Described his implementation of some fat client apps for his clients. I thinke he would have done better to just focus on some technology he used. I would have liked him to go into depth on the Updater Application Block. Instead he just described the code libraries he purchased and downloaded to implement a handful of applications. He clearly put a log of effort into his powerpoint presentation which included lots of fades and transitions.

Finally I attended Sam Gentile's talk on "Introduction to the .NET and CLR and Internals" This was a pretty good review of the CLR. Sam has spent way too much time playing with Rotor!!

The evening was capped by the Blogger "Dinner" organized by Jason Haley. It was great I had an opportunity to talk to Jason Bock, Carl Franklins, Richard Shaw, Don Demsak, Scott Watermasysk and others. I think some of the non-geeks who were at the bar watching the red-sox game were more than a little put off by the invasion of the nerds.

Friday, October 15, 2004

C# Edit and Continue is back.

Via Eric Gunnerson C# Edit and Continue will be in Whidbey!

Yay!!

Apparently Microsoft bowed to the pressure of bloggers and got it in.

By the way Somasegar reports that we are a week away from a new technology preview of Visual Studio 2005.

I'm looking for a version stable enough to put on my development machine.

I was scared off when my buddy Steve found that some VS 2003 projects were ending up with dependencies on the .NET 2.0 library.

Google Desktop

Wow I really like google desktop!

It indexes your word, excel, powerpoint and text documents as well as outlook/outlook express e-mails, internet explorer sites.

Now you can search your system with google!

When you google a search term the results on your computer show up first.

Also a new desktop link shows up on the google home page and you can search just your computer.

I bet Microsoft is reconsidering their decision to delay WinFS for Longhorn.

Code Camp II

I'm speaking at Code Camp II this weekend.

This is two full days of .net talks.

It should be great.

Come on by and see my talk at 1:15 on Sunday.

The talks are at Microsoft's Waltham office. Directions

I'll be covering the basics and some advanced topics.

Over the next weeks I'll be reprising some of the material here.

I'll be putting up links to the source code and the presentation materials so watch this site.

The Emperor's Clothes - powered by FeedBurner

Here's a reference to an rss feed for my blog:
The Emperor's Clothes RSS feed

I'm experimenting with feedburner since Blogger only supports atom.

Thursday, August 05, 2004

Welcome

This is my first entry into the blogosphere.

I am an independent software consultant. I work primarily on machine control, UI and algorithms. Although I have an extensive background in embedded systems, I currently am working primarily on the windows platform. Currently all my contracts include .Net and legacy components using com-interop to communicate.

I'm interested in providing an independent voice. I often want to voice a dissenting opinion that I do not hear from Redmon.

I'm often struck how proscriptive advice from Microsoft "experts" is used by people to justify their decisions without understanding the reason for the advice. For example, I worked on a project where the technical lead asserted we could not use MFC in our ATL based COM component because Microsoft said we shoudn't. What he failed to understand was that the experts in ATL were talking about active-x controls that would be downloaded from the internet. The motivation was to keep these COM components small so that download times would be small. In his case all the components were delivered to the customer on a CD. Size was not an issue. Nonetheless a group of people spent a long time re-writing existing code to remove the MFC dependencies.

When .Net came out we were advised to use remoting instead of COM. I love COM. It has provided a living for me by being hard enough to use to require companies to bring in experts to help them. There are a few things I don't like about remoting but in general it has been a great advance over COM. The systems I work on usually involve multiple components developed independently and COM or remoting provide the glue for all the objects to communicate. These system have all the components either on the same machine or within the same small intra-net. This object-oriented communications mechanism is a great architectural fit.

But now the experts such as Don Box are at it again. With the push towards Indigo the experts are telling us you shoud use Service Oriented Architecture. The push is to use a stateless model. Web services and their equivalent under Indigo do not mainatin object state. The object may be recreated on each call. This model is pretty useless if you are trying to communicate with an object that needs to maintain state. Now we can have an intialization method that returns a "cookie" to identify the object on the server and then pass the cookie with each method call. The server can then use the cookie to find the object and communicate with it directly. In C# remoting we call this cookie this. The intialization method is the constructor and the language nicely passes the this pointer to each method (as a hidden argument).

The experts say if you use remoting it won't scale. I DON'T WANT IT TO SCALE!!!! The SOA advice is great if your building a web server but everyone is not creating applications that have to go out over the web. The advice should be targeted. Unfortunately many people are going to read what Don Box has to say and not understand that his advice is targeting applications that need to scale over the web.

My advice is that if COM and remoting are meeting your needs you should use them. If you have an application that needs to be able to scale across large number of clients then SOA may be the most appropriate.