deft flux

A portal into the creative workings of David Meyer

Home

Welcome to my site.  Below are some highlights of the site followed by recent blog posts:

  • Duck Typing Project - A .NET class library written in C# that enables duck typing for any .NET language. The library has come to support many advanced features such as covariance and contravariance in class members.

The plague of new version notifications

Now, the concept is certainly good.  Have a program automatically check for new versions so that people can keep up to date.  But the fundamental flaw I find is that this check always takes place when you first start the program.  At this point, you're trying to use the program immediately and don't want to wait for it to download and install an update first.  So I always cancel out and never get the needed updates.  So the notification turns into nothing more than a nuisance.

So I thought of a solution, but it would be quite a feat to pull off, and it's not without problems.  What we need is an update agent that checks for updates behind the scenes and informs the user in a non-intrusive way based on how the user set it up.  A single program that will support checking for updates for multiple products.  That way the user would have a central place to view and optionally install these updates, or could configure them to automatically install when that program is not in use.  No more annoying pop-ups when you're trying to use the software.

But here's where the difficulty of such a solution comes in:  As far as I know, there is no standard for distributing updates.  To implement a standard, it would require the cooperation of the vendor for each piece of software.  The other option would be to make the program extensible so that anyone can write a plug-in for it to add support for a particular piece of software.  Now I could certainly write a framework to support this in my sleep and use duck typing for cross-version plug-in support, that would not be a challenge.  The problem is that I can't possibly write a plug-in for every piece of software in existence, or even most.  I'm not exactly good at promoting standards either.

But I'm wondering if I should make the solution for myself anyway, and implement plug-ins for the software that I use, and make it available for free and see what happens...

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Categories: General | Development
Posted by deftflux on Thursday, August 14, 2008 9:28 AM
Permalink | Comments (2) | Post RSSRSS comment feed

Safely invoking event delegates

Yesterday, my friend and I had an interesting conversation.  He was venting about the code one of his co-workers wrote which caused a problem he spent some time tracking down.  Here's the gist of it:

void RaiseEvent(EventArgs e) { Event(this, e); }

Now most .NET developers should immediately notice what's wrong here.  I certainly hope they do.  What if Event has not been subscribed to?  Then it is null, and invoking it will cause a NullReferenceException.  So this is how I have always invoked event delegates:

if (Event != null) { Event(null, e); }

But one thing my friend pointed out, which was actually new to me, is that the above code is actually not thread-safe, because another thread can unsubscribe from Event after the check for null and before the invocation.  So to make it thread safe, you would first copy the delegate reference to a local variable:

EventHandler handler = Event; if (handler != null) { handler(this, e); }

Now I thought, "This is a lot of code to write just to raise an event.  How can I make this shorter?"  So thanks to C# 3.0 extension methods and lambda expressions, I was able to reduce it to this:

Event.SafeInvoke(d => d(this, e));

Here's the extension method:

public static void SafeInvoke<T>(this T obj, Action<T> action) where T : class { if (obj != null) { action(obj); } }

This accomplishes both objectives: 1) Copy the delegate reference.  This is implicitly done when it is passed as a method parameter.  And 2) Check the delegate for null.  Now I know calling Event.SafeInvoke if Event is null looks a little odd, because you would think it would cause a NullReferenceException, but this is actually not the case with extension methods.  You can call an extension method on null.  This is because the compiler translates this to:

SafeInvoke(Event, d => d(this, e));

Now, unfortunately, you cannot set a restraint on generic types to restrict them to the Enum or Delegate types.  (This makes absolutely no sense to me, I think you should be able to.)  So the above extension method applies to all reference types.  At first I was afraid this would clutter the IntelliSense for non-delegate types, but actually, this extension method would be useful for any reference type.  What if, for instance, you want to call a method on an object but only if it isn't null?

obj.SafeInvoke(o => o.MyMethod());

And the best part is that this will also make the check for null thread-safe if the object in question has a greater scope than a local variable!  So, to wrap up this post, here are all the extension methods I wrote to support both return values and dispatching to another thread (feel free to plagiarize!):

public static void SafeInvoke<T>(this T obj, Action<T> action) where T : class { if (obj != null) { action(obj); } } public static TResult SafeInvoke<T, TResult>(this T obj, Func<T, TResult> func) where T : class where TResult : class { return obj.SafeInvoke(func, null); } public static TResult SafeInvoke<T, TResult>(this T obj, Func<T, TResult> func, TResult defaultResult) where T : class { TResult result = defaultResult; if (obj != null) { result = func(obj); } return result; } public static void SafeDispatch<T>(this T obj, Action<T> action) { if (obj != null) { action.BeginInvoke(obj, null, null); } }

Currently rated 5.0 by 2 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by deftflux on Monday, August 11, 2008 9:49 AM
Permalink | Comments (4) | Post RSSRSS comment feed