Archives
Blog Roll
Feed your Head
Random Thought Patterns
a Xavier Musy weblog production


Thursday, November 03, 2005
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
I have to say... this is pretty compelling:

VistaDB 2.1 database for .NET has been releasedThis 2.1 update includes over 60 improvements, including new support for .NET 2.0 and Visual Studio .NET 2005. VistaDB is a small-footprint, embedded SQL database alternative to Jet/Access, MSDE and SQL Server Express 2005 that enables developers to build .NET 1.1 and .NET 2.0 applications. Features SQL-92 support, small 500KB embedded footprint, free 2-User VistaDB Server for remote TCP/IP data access, royalty free distribution for both embedded and server, Copy 'n Go! deployment, managed ADO.NET Provider, data management and data migration tools. Free trial is available for download.
- Learn more about VistaDB
- Repost this to your blog and receive a FREE copy of VistaDB 2.1!


I mean, only a 500KB footprint for an embedded client full-featured RDBMS (RI, triggers, snapshot isolation level transaction, the works), no installation woes, has a .NET Data Provider, full text search, can migrate up to SQL Server, and future version will provide 'stored code' (presumably CLR-based stored procs). Pretty impressive. Will have to examine further.

Sunday, July 17, 2005
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
Junfeng Zhang posts about a very powerful and complicated issue related to publisher policy, redirection cross major/minor version, and using the latest version in .NET, and also answers very pertinent questions about guidelines for SDK developers who deploy assemblies to be consumed by others in the comments section. My posted comment question: whether or not to reroute 3rd party applications to the latest shared SDK assemblies if deemed compatible. The short answer: to let 3rd party apps decide to float or not via app config files (which means redeployment/update of those configurations if they wish to support the latest), unless the support policy is to only support the latest version, in which case publisher policies are in order, in conjunction with compatibility (which is of course difficult b/c of seemingly innocuous changes which can break compat; e.g., inserting an enum member).

As a side note, it’s import to realize that you have to have a publisher policy for each major.minor version of assembly. So if you wish to provide publisher policies to reroute to your latest 2.0.0.0 assembly, assuming you started at 1.0.0.0, you would not only need a publisher policy for 1.0.0.0->2.0.0.0 but also for any minor releases such as 1.1.0.0 -> 2.0.0.0, 1.2.0.0 to 2.0.0.0, etc…

Junfeng Zhang mentions that the focus today is on side-by-side versioning, and not latest-only versioning, and I hope as well that this issue is attended to at some point. Nevertheless it’s nice to have a recommended approach for the time being, so thank you Junfeng.

Sunday, June 06, 2004
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
Weak Events

There's a not entirely uncommon WinForms scenario whereby a long-lived event publisher has short-lived event subscribers, in which the subscriber(s) mistakenly never detach from the events, thereby causing memory leaks (can't be GC'ed), or worse (exceptions or resurrection caused by the handlers in the disposed subscribers).

A partial solution to this problem is to use weak events, such that the GC can occur on the subscribers. It is only a partial solution, because the short-lived subscribers hang around until GC occurs; and, GC typically isn’t explicitly done. Even if it is, it would assume the publisher knows when a subscriber needs to detach or is disposed, which isn’t likely.

Greg Schechter blogs about a specific related scenario in Avalon, and posts an interesting solution to the problem. Ian Griffiths provides an alternative solution using generics and weak handlers (instead of weak delegates).

I’ve written an alternate solution below. It also addresses 2 other common problems: subscribers subscribing to the same handler more than once (solved using the CombineUnique method), and subscribers throwing unhandled exceptions, thereby stopping any remaining subscribers in the invocation list from receiving the events (solved using the InvokeSafe method).




public class WeakMulticastDelegate
{
private WeakReference weakRef;
private MethodInfo method;
private WeakMulticastDelegate prev;

public WeakMulticastDelegate(Delegate realDelegate)
{
this.weakRef = new WeakReference(realDelegate.Target);
this.method = realDelegate.Method;
}


public static WeakMulticastDelegate Combine(WeakMulticastDelegate weakDelegate, Delegate realDelegate)
{
if ( realDelegate == null )
return null;
return ( weakDelegate == null ) ? new WeakMulticastDelegate(realDelegate) : weakDelegate.Combine(realDelegate);
}


public static WeakMulticastDelegate CombineUnique(WeakMulticastDelegate weakDelegate, Delegate realDelegate)
{
if ( realDelegate == null )
return null;
return ( weakDelegate == null ) ? new WeakMulticastDelegate(realDelegate) : weakDelegate.CombineUnique(realDelegate);
}

private WeakMulticastDelegate Combine(Delegate realDelegate)
{
WeakMulticastDelegate head = new WeakMulticastDelegate( realDelegate );
head.prev = this.prev;
this.prev = head;
return this;
}

// provides unique subscribers: makes sure the the target & method are not already a subscriber
private WeakMulticastDelegate CombineUnique(Delegate realDelegate)
{
bool found = false;
if ( prev != null )
{
WeakMulticastDelegate curNode = prev;
while (!found && curNode != null )
{
if ( curNode.weakRef.IsAlive && curNode.weakRef.Target == realDelegate.Target &&
curNode.method == realDelegate.Method )
{
found = true;
}
curNode = curNode.prev;
}
}
return found ? this : Combine(realDelegate);
}

public static WeakMulticastDelegate Remove(WeakMulticastDelegate weakDelegate, Delegate realDelegate)
{
if ( realDelegate == null || weakDelegate == null )
return null;
return weakDelegate.Remove(realDelegate);
}

private WeakMulticastDelegate Remove(Delegate realDelegate)
{
if ( weakRef.IsAlive &&
weakRef.Target == realDelegate.Target &&
method == realDelegate.Method )
{
return this.prev;
}

WeakMulticastDelegate current = this.prev;
WeakMulticastDelegate last = this;
while ( current != null )
{
if ( current.weakRef.IsAlive &&
current.weakRef.Target == realDelegate.Target &&
current.method == realDelegate.Method )
{
last.prev = current.prev;
current.prev = null;
break;
}
last = current;
current = current.prev;
}

return this;

}

public void Invoke(object[] args)
{
WeakMulticastDelegate current = this;
while ( current != null )
{
if ( current.weakRef.IsAlive )
{
current.method.Invoke(current.weakRef.Target, args);
}
current = current.prev;
}
}

// provides safe invocation: such that a subscriber throwing in it's handler won't stop
// other subscribers from receiving
public void InvokeSafe(object[] args)
{
WeakMulticastDelegate current = this;
while ( current != null )
{
if ( current.weakRef.IsAlive )
{
try
{
current.method.Invoke(current.weakRef.Target, args);
}
catch(Exception ex)
{
Console.WriteLine(ex);
}
}
current = current.prev;
}
}

}



A publisher can expose an event in the following manner:


private WeakMulticastDelegate weakEventHandler = null;

public event EventHandler SomeEvent
{
add
{
weakEventHandler = WeakMulticastDelegate.CombineUnique(weakEventHandler, value);
}
remove
{
weakEventHandler = WeakMulticastDelegate.Remove(weakEventHandler, value);
}
}


And can fire the event this way:


if ( this.weakEventHandler != null )
weakEventHandler.Invoke( new object[]{this, new EventArgs()} );


Monday, February 23, 2004
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
I did it my way

Scoble writes about those pesky designers. If you actually subscribe to more than one feed, you'll soon come to the realization that a news aggregator is indispensable to be productive. Once that happens, you'll likely be consuming rss/atom, and not HTML, which makes the design of a blog much less important than the content -- as it should be. Like Scoble, I use NewsGator for a news aggregator. The nice thing about NewsGator is that it lets you edit the style sheet which formats the feeds which end up in your news folders. So not only is the original style gone, but you can inject your own, and damn those overrated designs :) An interesting statistic would be what percentage of Scoble's readers use a web client vs. a news aggregator.

Wednesday, February 18, 2004
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
Reflection and out parameters

So I was asked today how to invoke a method with an out param using reflection. I didn't know off hand. As it turns out, it's a bit more obscure then I expected. Apparently, the type name passed to GetType needs to be appended with a '&' to denote a reference to that type. Here's an example of invoking a method with a string out param via reflection:

Type type = typeof(MyType);
object o = Activator.CreateInstance(type);
MethodInfo mi = type.GetMethod("MyMethod", new Type[]{Type.GetType("System.String&")});
object[] parms = new object[1];
mi.Invoke(o, parms);
string outValue = (string)parms[0];



Monday, January 26, 2004
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
Blogger syndication and NewsGator

So, it appears Blogger finally supports syndication for those of us who don't have a Pro account.  Awesome!  However, because the syndication format Blogger uses; namely Atom, isn't supported by SharpReader, my blog reader of choice, I'll likely be switching to NewsGator.  I'm currently test driving NewsGator.  So far, so good.  The Outlook integration is very slick.  Search folders are must.  Currently, I have 108 feeds, so being able to filter, mark, etc.. those posts are quite a time saver.  Nice Blogger plugin for writing posts too (I'm trying that on this very post). 

Saturday, September 20, 2003
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
 
Deteriorating fan noise on my graphics card has led to cleaning, then exploratory surgery, followed by organ transplant of the graphics card cooler. Surgery as follows: stick flathead between cooler and old debit card placed underneath the fan, and twist, popping off the thermal-glued cooler from the GPU. Use tweezers to detach old fan pesky end to the old power cord from the video card. Nurse, 10 CCs of acetone and a swap and scalpel to shave off the old thermal glue from the chip. After GPU is cleaned, added thin layer of new thermal goo and spread. Place new cooler on chip & pop pins in holes. Place new RAM heat sinks on with double sided tape. Plug to power supply. Surgery a complete success.

 
Well, it looks like I won't be getting this feed syndicated anytime soon using Blogger. According to a recent announcement, Blogger Pro won't be offered any longer :(


Powered by Blogger

The information in this weblog is provided "AS IS" with no warranties, and confers no rights. This weblog does not represent the thoughts, intentions, plans or strategies of Seed Industries. It is solely my opinion.
Copyright © 2003, Xavier Musy. All right are reserved.