<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-19743873</id><updated>2011-11-28T11:40:58.847+11:00</updated><category term='Rx Framework'/><category term='PdfCompressor'/><category term='Vista'/><category term='Exchange'/><category term='Outlook'/><category term='dynamic'/><category term='SQL Server'/><category term='USB 306'/><category term='Olib'/><category term='Windows Server 2008'/><category term='Windows'/><category term='IceTV'/><category term='Reactive'/><category term='view performance'/><category term='InFusion'/><category term='C++'/><category term='compression'/><category term='Sierra Wireless'/><category term='Google Apps for Domains'/><category term='union'/><category term='P/Invoke'/><category term='contravariance'/><category term='SUSER_SNAME'/><category term='generic arithmetic'/><category term='Mac'/><category term='LINQ to SQL'/><category term='strings'/><category term='Home Automation'/><category term='Linq expressions'/><category term='covariance'/><category term='xml'/><category term='Vantage'/><category term='21 meg'/><category term='EventGhost'/><category term='PDF'/><category term='streaming'/><category term='Telstra'/><category term='multithreading'/><category term='Observable'/><category term='Parallels'/><category term='C#'/><category term='Boot Camp'/><category term='Design Center'/><category term='Linq to Events'/><category term='JBIG2'/><category term='drivers'/><category term='online backup'/><category term='generics'/><category term='Mozy'/><category term='PLINQO'/><category term='Apple Remote'/><category term='Next-G'/><category term='Nine'/><category term='.NET'/><title type='text'>Fil's Blog</title><subtitle type='html'>Fil Mackay's blog on the world in motion.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Fil Mackay</name><uri>http://www.blogger.com/profile/17537644647957871265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>43</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-19743873.post-6153885028271257039</id><published>2011-05-03T09:20:00.002+10:00</published><updated>2011-05-03T09:50:55.726+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Reactive'/><title type='text'>Reactive Extensions release v1.0.10425</title><content type='html'>I just ported my projects to the &lt;a href="http://social.msdn.microsoft.com/Forums/en-US/rx/thread/527002a3-18af-4eda-8e35-760ca0006b98"&gt;latest Rx&lt;/a&gt;. Here's the highlights:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;- Namespaces are more split-out, System.Reactive now contains lots of sub-namespaces like System.Reactive.Linq, System.Reactive.Subjects&lt;/div&gt;&lt;div&gt;- Less assemblies - gone is System.CoreEx; everything is pretty much in System.Reactive now&lt;/div&gt;&lt;div&gt;- TPL 3.5 stopped; System.Interactive, System.Linq.Async, RxJS on pause&lt;/div&gt;&lt;div&gt;- Lots of name simplification: eg. Window*/Buffer*/Generate* are now just overloads of Window/Buffer/Generate&lt;/div&gt;&lt;div&gt;- Performance improvements - Subject now replaced with Subject.Synchronize, FastSubject with Subject.&lt;/div&gt;&lt;div&gt;- Now compatible with &lt;a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=4738205d-5682-47bf-b62e-641f6441735b&amp;amp;displaylang=en"&gt;Async CTP SP1&lt;/a&gt;&lt;/div&gt;&lt;div&gt;- General cleanup of schedulers, new VirtualTimeScheduler and HistoricalScheduler&lt;/div&gt;&lt;div&gt;- Observable.CreateWithDisposable is now an overload of Observable.Create&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I was still using &lt;a href="http://code.msdn.microsoft.com/ParallelExtensionsExtras-2fdc7629"&gt;ParallelExtensionsExtras&lt;/a&gt; for some extra functionality over Rx/TPL, but have now managed to remove it from my dependencies.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-6153885028271257039?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/6153885028271257039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=6153885028271257039' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/6153885028271257039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/6153885028271257039'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2011/05/reactive-extensions-release-v1010425.html' title='Reactive Extensions release v1.0.10425'/><author><name>Fil Mackay</name><uri>http://www.blogger.com/profile/17537644647957871265</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-6465096848583184774</id><published>2010-04-14T13:49:00.006+10:00</published><updated>2010-04-14T14:18:47.431+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='multithreading'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Lock-free multi-threading</title><content type='html'>I was recently looking for a way to combine two Interlocked.CompareExchange() calls, do do something like this (atomically):&lt;br /&gt;&lt;br /&gt;- If 0, then 1&lt;br /&gt;- If 2, then 3&lt;br /&gt;&lt;br /&gt;I looked some ways to combine two Interlocked.CompareExchange calls in sequences, but it seemed pretty impossible to ensure correctness. Then a mate referred me to &lt;a href="http://www.amazon.com/Concurrent-Programming-Windows-Joe-Duffy/dp/032143482X?ie=UTF8&amp;amp;tag=fisbl03-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969" target="_blank"&gt;Concurrent Programming on Windows&lt;/a&gt;&lt;img alt="" border="0" height="1" src="http://www.assoc-amazon.com/e/ir?t=fisbl03-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=032143482X" style="border: none !important; margin: 0px !important; padding: 0px !important;" width="1" /&gt;. Very good - had read that one in the past.&lt;br /&gt;&lt;br /&gt;I put together a nice generic technique in, to come up with this (some typos in the original code corrected):&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;public static class Concurrency&lt;br /&gt;{&lt;br /&gt;    public static int Atomic(ref int result, Func&lt;int, int=""&gt; func)&lt;br /&gt;    {&lt;br /&gt;        int oldValue, newValue;&lt;br /&gt;        do&lt;br /&gt;        {&lt;br /&gt;            oldValue = result;&lt;br /&gt;            newValue = func(oldValue);&lt;br /&gt;        } while (Interlocked.CompareExchange(ref result, newValue, oldValue) != oldValue);&lt;br /&gt;&lt;br /&gt;        return oldValue;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;Which can then be used:&lt;br /&gt;&lt;pre&gt;Concurrent.Atomic(ref val, x =&amp;gt;&lt;br /&gt;{&lt;br /&gt;    if (x == 0)&lt;br /&gt;        return 1;&lt;br /&gt;    if (x == 2)&lt;br /&gt;        return 3;&lt;br /&gt;    return x;&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;This provides a great way to combine multiple Interlocked.CompareExchange operations together in a consistent way, where there isn't a *massive* amount of contention over the result. The only down side I can see is the overhead of the delegate, which would need to be optimised out to work in a very performance intensive scenario.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-6465096848583184774?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/6465096848583184774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=6465096848583184774' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/6465096848583184774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/6465096848583184774'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2010/04/lock-free-multi-threading.html' title='Lock-free multi-threading'/><author><name>Fil Mackay</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_G70UoPpVIT4/SrtEUEHC8SI/AAAAAAAAAAM/T51ab87N77g/S220/Fil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-4421657223885908366</id><published>2009-12-27T22:42:00.003+11:00</published><updated>2009-12-27T22:54:05.778+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='contravariance'/><title type='text'>out parameters and covariance</title><content type='html'>I was disappointed to discover that out parameters are actually ref parameters, plus some compiler rules. That means the following does not work:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; interface ITest&lt;out&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;     void Method2(out T t);  // T must be input safe? Huh?&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;     //void Method2(ref T t);  // OK this should fail&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; }&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;(see &lt;a href="http://blogs.msdn.com/ericlippert/archive/2009/09/21/why-do-ref-and-out-parameters-not-allow-type-variation.aspx"&gt;this &lt;/a&gt;discussion)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I'd already reported to Microsoft as a &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=522012"&gt;bug&lt;/a&gt;. Oh well, looks like it will come back as 'by design'.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;My view is that 'out' should be recognised by the CLI, and therefore not be as restricted as 'ref' is. This would no doubt require that 'out' parameters not actually pass in a value (I had assumed this was not the case, but it actually does in the debugger..).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In short, this seriously restricts the usefulness of covariance with generic interfaces in C# 4.0.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-4421657223885908366?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/4421657223885908366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=4421657223885908366' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/4421657223885908366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/4421657223885908366'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2009/12/out-parameters-and-covariance.html' title='out parameters and covariance'/><author><name>Fil Mackay</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_G70UoPpVIT4/SrtEUEHC8SI/AAAAAAAAAAM/T51ab87N77g/S220/Fil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-5685703790039349825</id><published>2009-11-03T14:08:00.005+11:00</published><updated>2009-12-27T23:02:48.964+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='covariance'/><category scheme='http://www.blogger.com/atom/ns#' term='generics'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Olib'/><category scheme='http://www.blogger.com/atom/ns#' term='contravariance'/><title type='text'>Covariance and contravariance</title><content type='html'>I recently upgraded an "asynchronous observable framework" (working title: Olib) to .NET 4.0 beta 2. The reason for this was the new "reactive" pieces (IObservable&lt;&gt; et al.) but I ended up not using them since I needed a different interaction pattern (more of that in a future post). There wasn't anything more I wanted to use, but found a few interesting pieces which dramatically helped me:&lt;div&gt;&lt;ul&gt;&lt;li&gt;The new ISet&lt;&gt; generic interface, now implemented by HashSet&lt;&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/dd799517(VS.100).aspx"&gt;Generics covariance and contravariance&lt;/a&gt; (keep reading)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;Covariance and contravariance have been implemented for some time in the .NET world, in various forms (parameters, delegates etc.). This new feature makes some seemingly minor additions to generic interfaces and generic delegates (Func&lt;&gt; and Action&lt;&gt;). eg:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;interface IEnumerable&lt;&lt;/span&gt;&lt;span&gt;&lt;span&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="color:#9999FF;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;out&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="color:#009900;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;T&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This "out" keyword denotes the type as only usable as output within the interface, and therefore considered contravariant. This means that you can do:&lt;/div&gt;&lt;pre&gt;IEnumerable&amp;lt;string&amp;gt; i = new[] { "0", "1", "2", "3" }; IEnumerable&amp;lt;object&amp;gt; o = i;&lt;/pre&gt;&lt;div&gt;Note you cannot do anything that requires anything other than the most basic cast, eg. boxing:&lt;/div&gt;&lt;pre&gt;IEnumerable&amp;lt;int&amp;gt; i = new[] { 0, 1, 2, 3 };&lt;br /&gt;IEnumerable&amp;lt;object&amp;gt; o = i; // cannot implicitly convert&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;One of the best things about this (and the reason I used it for Olib) was that you can write much more powerful extension methods now, since code you write to operate on "IEnumerable&lt;icomparable&gt;" will now work with any enumerable whose items support IComparable.&lt;/icomparable&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;div&gt;For example, in Olib I'm creating Linq aggregates:&lt;/div&gt;&lt;pre&gt;public static IAsyncObservableValue&amp;lt;TInner&amp;gt; Sum&amp;lt;TInner&amp;gt;(this IAsyncObservableSet&amp;lt;IAsyncObservableValue&amp;lt;TInner&amp;gt;&amp;gt; innerSet)&lt;br /&gt;&lt;/pre&gt;&lt;div&gt;Using the right contravariant constraints (and I have to admit a major refactor to make it confirm to the rules), I can now use this extension method on types such as AsyncObservableSet&amp;lt;asyncobservablevalue&amp;lt;t&amp;gt;&amp;gt; - as the types inherit from their respective interfaces.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Tip: I found in some cases where I could not easily comply with the contravariant constraints, I split my interface into two - one "read only" (contravariant) interface and one "read/write" (invariant).&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Can't go back to .NET 3.5 now.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-5685703790039349825?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/5685703790039349825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=5685703790039349825' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/5685703790039349825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/5685703790039349825'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2009/11/covariance-and-contravariance.html' title='Covariance and contravariance'/><author><name>Fil Mackay</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_G70UoPpVIT4/SrtEUEHC8SI/AAAAAAAAAAM/T51ab87N77g/S220/Fil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-8583141423540260223</id><published>2009-11-03T09:52:00.007+11:00</published><updated>2009-11-03T10:29:52.754+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq expressions'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='generic arithmetic'/><title type='text'>Generic arithmetic in C#</title><content type='html'>One problem that has bugged me is the lack of an IArithmetic&lt;&gt; or similar interface to allow generic values to be added together. I had written a MSIL-reflecting routine to statically create arithmetic methods at runtime, but have recently converted it to Linq Expressions.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The downside? No compile-time type checking. You'll blow-up at runtime if the types cannot be "arithmetized".&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here's the code:&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="brush: csharp"&gt;&lt;br /&gt;  public static class Arithmetic&amp;lt;TLeft, TRight&amp;gt;&lt;br /&gt;  {&lt;br /&gt;      public static Func&amp;lt;TLeft, TRight, TLeft&amp;gt; Add = CreateBinaryOperator(Expression.Add);&lt;br /&gt;      public static Func&amp;lt;TLeft, TRight, TLeft&amp;gt; Subtract = CreateBinaryOperator(Expression.Subtract);&lt;br /&gt;      public static Func&amp;lt;TLeft, TRight, TLeft&amp;gt; Multiply = CreateBinaryOperator(Expression.Multiply);&lt;br /&gt;      public static Func&amp;lt;TLeft, TRight, TLeft&amp;gt; Divide = CreateBinaryOperator(Expression.Divide);&lt;br /&gt;      public static Func&amp;lt;TLeft, TRight, TLeft&amp;gt; Modulo = CreateBinaryOperator(Expression.Modulo);&lt;br /&gt;&lt;br /&gt;      public static Func&amp;lt;TLeft, TRight, TLeft&amp;gt; CreateBinaryOperator(Func&amp;lt;Expression,Expression,BinaryExpression&amp;gt; op)&lt;br /&gt;      {&lt;br /&gt;          // declare the parameters&lt;br /&gt;          var paramA = Expression.Parameter(typeof(TLeft), "a");&lt;br /&gt;          var paramB = Expression.Parameter(typeof(TRight), "b");&lt;br /&gt;          // add the parameters together&lt;br /&gt;          BinaryExpression body = op(paramA, paramB);&lt;br /&gt;          // compile it&lt;br /&gt;          return Expression.Lambda&amp;lt;Func&amp;lt;TLeft,TRight,TLeft&amp;gt;&amp;gt;(body, paramA, paramB).Compile();&lt;br /&gt;      }&lt;br /&gt;  }&lt;br /&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-8583141423540260223?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/8583141423540260223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=8583141423540260223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/8583141423540260223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/8583141423540260223'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2009/11/generic-arithmetic-in-c.html' title='Generic arithmetic in C#'/><author><name>Fil Mackay</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_G70UoPpVIT4/SrtEUEHC8SI/AAAAAAAAAAM/T51ab87N77g/S220/Fil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-5259449840224747980</id><published>2009-09-24T20:06:00.004+10:00</published><updated>2009-09-24T20:23:01.500+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Rx Framework'/><category scheme='http://www.blogger.com/atom/ns#' term='Observable'/><category scheme='http://www.blogger.com/atom/ns#' term='Linq to Events'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Reactive'/><title type='text'>Continuous / Observable / Linq / to Events</title><content type='html'>I have spent the last couple of weeks researching the above area, especially in relation to an observable C# library I built a couple of years ago. A lot has happened since, but the event that sticks out the most (and caused me to re-investigate) was the Reactive (Rx) Framework that leaked out with the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Silverlight&lt;/span&gt; Toolkit. &lt;a href="http://www.julmar.com/blog/mark/2009/08/03/UsingRxLinqToEventsWithWPF.aspx"&gt;This post&lt;/a&gt; has a handy guide to moving Rx to the desktop .NET platform, from the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Silverlight&lt;/span&gt; core. Most research involved watching hours of (mostly repetitive) video, but it all got through in the end.&lt;br /&gt;&lt;br /&gt;Whilst the theoretical framework behind the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;monad&lt;/span&gt;/&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;monoid&lt;/span&gt;/"dual of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;IEnumerable&lt;/span&gt;" is pretty interesting, I cant help but be left with the feeling that &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;something's&lt;/span&gt; been missed here. The whole thing really did not make any sense to me (in relation to creating an observable/reactive framework) until the following clicked: this is not about collections.&lt;br /&gt;&lt;br /&gt;I generally use the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;IEnumerable&lt;/span&gt; construct day-to-day to navigate collections, of one form or another. I had mistakenly thought that the mathematical dual of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;IEnumerable&lt;/span&gt; would "reverse" it's behaviour in some kind of real-world scenario. Here I was thinking some collection/enumerable object that you could subscribe to. It turns it it is, of a kind, except the dimension is totally different. Whilst there is a spatial data dimension in collections I would use &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;IEnumerable&lt;/span&gt;; the dimension of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;IObservable&lt;/span&gt; is time. &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;IObservable&lt;/span&gt; allows you to observe an individual value over time in an event-driven form, whilst &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;IEnumerable&lt;/span&gt; allows you to navigate your own way along a collection of items.&lt;br /&gt;&lt;br /&gt;If I had thought of &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;IEnumerable&lt;/span&gt; being used to extract the evolving changes of a discrete value over time, then maybe &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;IObservable&lt;/span&gt; would have made perfect sense; but the fact is I saw &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;IEnumerable&lt;/span&gt; being useful to navigate over a collection of completely &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_15"&gt;separate&lt;/span&gt; items/values/objects.&lt;br /&gt;&lt;br /&gt;Now this has all clicked into place, I need to apply my observable library which is more focused on collections. I observable collections, where the collection members themselves are changing and can be queried. From what I've seen so far, Rx is more focused on events/discrete values which is a different thing from handling inserts/changes/deletes to a set.&lt;br /&gt;&lt;br /&gt;My view is the Reactive Framework is totally going to change the way apps are developed (for me at least anyway) - just like Linq in general has already.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-5259449840224747980?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/5259449840224747980/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=5259449840224747980' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/5259449840224747980'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/5259449840224747980'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2009/09/continuous-observable-linq-to-events.html' title='Continuous / Observable / Linq / to Events'/><author><name>Fil Mackay</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='31' src='http://4.bp.blogspot.com/_G70UoPpVIT4/SrtEUEHC8SI/AAAAAAAAAAM/T51ab87N77g/S220/Fil.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-7511479944565332070</id><published>2009-09-18T07:30:00.003+10:00</published><updated>2009-09-18T07:34:49.145+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='LINQ to SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='PLINQO'/><title type='text'>PLINQO - strange name, nice concept</title><content type='html'>I've been writing a lot of code around Linq to SQL, and are getting concerned about the future support etc. from Microsoft. Competition with Linq to Entities (I only need 1:1 mapping so Linq to SQL hits the sweet spot for me), means less focus on this tool. For starters there should be synchronisation of database changes, support for enums, etc.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://plinqo.com"&gt;PLINQO&lt;/a&gt; is built on the &lt;a href="http://www.codesmithtools.com/"&gt;CodeSmith Tools&lt;/a&gt;, which is a template-driven code generator. The nice thing about that is you can get in and change/create templates, rather than take the hard-coded SQLMETAL view of the world. Nice!&lt;br /&gt;&lt;br /&gt;Regards, Fil.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-7511479944565332070?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/7511479944565332070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=7511479944565332070' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/7511479944565332070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/7511479944565332070'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2009/09/plinqo-strange-name-nice-concept.html' title='PLINQO - strange name, nice concept'/><author><name>Fil Mackay</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-8534095322076958571</id><published>2009-04-01T21:58:00.003+11:00</published><updated>2009-04-01T22:21:43.274+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='21 meg'/><category scheme='http://www.blogger.com/atom/ns#' term='Sierra Wireless'/><category scheme='http://www.blogger.com/atom/ns#' term='Telstra'/><category scheme='http://www.blogger.com/atom/ns#' term='USB 306'/><category scheme='http://www.blogger.com/atom/ns#' term='Next-G'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Server 2008'/><title type='text'>Using Sierra Wireless USB 306 modem on Windows Server 2008</title><content type='html'>I recently started using Windows Server 2008 as a workstation platform on my Macbook Pro - yes the whole OS X thing was good, except for developing Windows software. Winding back to XP wasn't very appealing given the server features, terminal services &amp;amp; RAM restrictions, something that 2008 does not suffer from.&lt;br /&gt;&lt;br /&gt;To my suprise the new Telstra/Next-G 21 meg USB modem, did not support Winodws Server 2008. How rude. I contacted Telstra and Sierra Wireless: Telstra had no idea what Windows Server 2008 even was, and Sierra Wireless simply stated they only supported Windows 2000, XP and Vista. So much for Vista drivers being compatible with 2008.&lt;br /&gt;&lt;br /&gt;I investigated the various .INF hacks around for different devices - I used one to use Bluetooth on Windows Server 2008. There are often filters in the .INF's to tell it to only work on certain operating systems. Widening these filters often works, but there is the risk it will not.&lt;br /&gt;&lt;br /&gt;Anyway, it turned out the solution in this case was a lot simpler, and much less risky and error-prone than editing .INF drivers. Here's the process:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Insert the device and install it as per normal (it takes a few minutes); you'll find that it will say that it cannot find a driver for a bunch of devices near the end (it's actually all the one physical device).&lt;/li&gt;&lt;li&gt;Choose "Locate and install driver software (recommended)"&lt;/li&gt;&lt;li&gt;Choose "I don't have the disc. Show me other options."&lt;/li&gt;&lt;li&gt;Choose "Browse my computer for driver software (advanced)"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Point it to the path: C:\Program Files\Telstra\Telstra Turbo Connection Manager\DriverInstaller\Drivers\WinVista\32bit, and click "Next". Presumably the 64 bit Vista driver will work fine with 64-bit 2008.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The device will install, click "Close"&lt;/li&gt;&lt;li&gt;Repeat the above process of locating drivers as many times as it appears (8 or so); this will take some time to complete and you'll get the feeling of Ground Hog Day - but it does end.&lt;/li&gt;&lt;li&gt;It's ready to use!&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-8534095322076958571?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/8534095322076958571/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=8534095322076958571' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/8534095322076958571'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/8534095322076958571'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2009/04/using-sierra-wireless-usb-306-modem-on.html' title='Using Sierra Wireless USB 306 modem on Windows Server 2008'/><author><name>Fil Mackay</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-1386283602271686357</id><published>2009-03-12T18:38:00.003+11:00</published><updated>2009-03-12T19:54:09.237+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Outlook'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Apps for Domains'/><category scheme='http://www.blogger.com/atom/ns#' term='Exchange'/><title type='text'>Migrating from Outlook to GMail</title><content type='html'>I made the move recently from Exchange/Outlook to Google Apps for Domains (GMail on your own domain name). The reason I did this was lugging my 4GB of email history around was making Outlook a real hog on my laptop/PC and was becoming more hungry/unreliable as time went on. It does not seem to scale well with increasing database size, and takes a lot of resources.&lt;br /&gt;&lt;br /&gt;Enter GMail - no load on my PC at all, fully portable, and to seal the deal - an "offline" function (using Google Gears) to enable me to browse/write emails while disconnected (it does happen).&lt;br /&gt;&lt;br /&gt;In all the experience was pretty positive, with the exception of migrating the email history. The main task required is to change the DNS MX entries to point to Google - plenty is written on that and Google have pretty good instructions on this.&lt;br /&gt;&lt;br /&gt;Migrating email history is another story - there is a plethora of options here: multiple upload channels (POP3, IMAP pull, IMAP push, migration API). The latter is the most serious, and scalable option, but only works with the Premier (paid) verison of Google Apps.&lt;br /&gt;&lt;br /&gt;The best option I found was to attach the new GMail account as a IMAP account to my Outlook, and copy the emails &lt;span style="font-weight: bold;"&gt;from a .PST archive&lt;/span&gt;. I found that this was far more reliable than copying directly from an Exchange account (.OST cache archive) - not sure why but copying from Exchange was very unreliable. Even then I was unable to copy it all over in one hit - but one year at a time did work. Doing this via IMAP gives you good control over what-goes-where in your new GMail account.&lt;br /&gt;&lt;br /&gt;To migrate a significant number of email accounts I'd certainly suggest getting the Premier Edition of Google Apps, and go for a migration product (there are heaps around) that will no doubt do this much better and faster.&lt;br /&gt;&lt;br /&gt;Regards, Fil.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-1386283602271686357?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/1386283602271686357/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=1386283602271686357' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/1386283602271686357'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/1386283602271686357'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2009/03/migrating-from-outlook-to-gmail.html' title='Migrating from Outlook to GMail'/><author><name>Fil Mackay</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-7411512496513008636</id><published>2008-04-23T16:13:00.005+10:00</published><updated>2008-04-23T16:29:25.938+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='P/Invoke'/><category scheme='http://www.blogger.com/atom/ns#' term='union'/><category scheme='http://www.blogger.com/atom/ns#' term='strings'/><title type='text'>Using strings within unions in P/Invoke</title><content type='html'>I googled for hours finding this solution. If you are trying to use strings within unions with P/Invoke, here is the answer. This is not possible normally since string is a reference type, and these can't be mixed in unions (confuses the garbage collector)&lt;br /&gt;&lt;br /&gt;Use the unsafe "fixed" array modifier:&lt;br /&gt;&lt;br /&gt;union blah&lt;br /&gt;{&lt;br /&gt;    int i;&lt;br /&gt;    char[2] s;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[StructLayoutAttribute(LayoutKind.Sequential, CharSet=CharSet.Ansi)]&lt;br /&gt;unsafe public struct Blah&lt;br /&gt;{&lt;br /&gt;    [FieldOffsetAttribute(0)]&lt;br /&gt;    public int i;&lt;br /&gt;&lt;br /&gt;    [FieldOffsetAttribute(0)]&lt;br /&gt;    public fixed char s[2];&lt;br /&gt;}&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-7411512496513008636?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/7411512496513008636/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=7411512496513008636' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/7411512496513008636'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/7411512496513008636'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2008/04/using-strings-within-unions-in-pinvoke.html' title='Using strings within unions in P/Invoke'/><author><name>Fil Mackay</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-7629071306249070224</id><published>2008-02-10T11:16:00.000+11:00</published><updated>2008-02-10T11:23:02.556+11:00</updated><title type='text'>Hauppauge 1100 with Vista - solution cannot find tuner card problem</title><content type='html'>I encountered the common "I cant get Vista Media Center to recognise my 1100 tuner card" that noone seems to be able to solve when reinstalling Vista. Found the solution (probably what I must have done last time):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Use HCWCLEAR.EXE to remove any existing drivers&lt;/li&gt;&lt;li&gt;Download the raw drivers from the UK site: &lt;a href="http://www.hauppauge.co.uk/pages/support/support_driversonly.html"&gt;http://www.hauppauge.co.uk/pages/support/support_driversonly.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Manually install the driver: skip the automatic process of finding a driver (the standard MS ones don't work). Then go find the "unknown" devices in Device Manager: right click and choose "Update driver"&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-7629071306249070224?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/7629071306249070224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=7629071306249070224' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/7629071306249070224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/7629071306249070224'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2008/02/hauppauge-1100-with-vista-solution.html' title='Hauppauge 1100 with Vista - solution cannot find tuner card problem'/><author><name>Fil Mackay</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-8259309305057648021</id><published>2008-01-13T21:48:00.001+11:00</published><updated>2008-01-13T22:07:54.120+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mozy'/><category scheme='http://www.blogger.com/atom/ns#' term='online backup'/><title type='text'>Great backup solution</title><content type='html'>I have signed up a whole lot of family and friends to a great service that makes the backup headache a thing of the past: &lt;a href="https://mozy.com/?code=6S8MP3"&gt;Mozy&lt;/a&gt; (owned by EMC).&lt;br /&gt;&lt;br /&gt;Mozy uploads your files on a daily basis to Mozy's servers. If you need a file back, you can download it (or get them to FedEx a DVD for larger emergencies), plus you can choose the date on which you want the snapshot to be taken. You can even access your Mozy store via a virtual drive on your computer, which is really handy. Mozy only uploads changes to your data, and as such is really efficient, nightly while you're not using your PC or broadband connection. You'll hardly notice it after the initial upload.&lt;br /&gt;&lt;br /&gt;The best thing is that Mozy give away for FREE personal accounts that hold up to 2GB! That's plenty for the average bear. It's a bit hard to find (they must prefer you to pay) but &lt;a href="http://mozy.com/registration/free/?code=6S8MP3"&gt;register here&lt;/a&gt;. Make sure you use the referal code "6S8MP3" when signing up in order to get an extra 256MB of space (at time of writing).&lt;br /&gt;&lt;br /&gt;I personally subscribe to the unlimited plan (USD5/month), and have about 14GB of data - 95% of which is original digital camera images. No need for physical off-site backups any more! (except for the home videos) For the record it took about a week to get the initial snapshot of data uploaded to Mozy's servers. Since then it has been lightning fast!&lt;br /&gt;&lt;br /&gt;Go ahead and solve your personal backup problems once and for all! And if you're like me, and your family/friends technology problems inevitably come back to me your problem, buy yourself an easy way out...&lt;br /&gt;&lt;br /&gt;(Disclosure: Mozy didn't give me anything except peace-of-mind!)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-8259309305057648021?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/8259309305057648021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=8259309305057648021' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/8259309305057648021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/8259309305057648021'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2008/01/great-backup-solution.html' title='Great backup solution'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-4950685187912165212</id><published>2008-01-13T21:42:00.000+11:00</published><updated>2008-01-13T21:48:15.244+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='EventGhost'/><category scheme='http://www.blogger.com/atom/ns#' term='Apple Remote'/><category scheme='http://www.blogger.com/atom/ns#' term='Boot Camp'/><title type='text'>Using Apple remote in Boot Camp</title><content type='html'>When I unpacked my Mac, I thought "what do I do with this?" - I have to do something!&lt;br /&gt;&lt;br /&gt;I found a great use for it, using a utility called &lt;a href="http://www.eventghost.org/"&gt;EventGhost&lt;/a&gt;. It's an open source automation tool for Windows - nothing to do with Boot Camp directly. Essentially it lets you set up triggers, and create actions that run in response to those events.&lt;br /&gt;&lt;br /&gt;One of the cool triggers it supports is Apple Remote buttons! I personally use the left/right button on the remote to fire left/right key-presses. Good for PowerPoint presentations. By default I tihnk left/right do prev/next track (used by Windows Media).&lt;br /&gt;&lt;br /&gt;I now think EventGhost is a must-have utility for all those general automation tasks, like switching things on/off when sleeping or hybernating, undocking etc. Very easy to use, it does not require any script or programming skills - very user friendly after you get over the dawnting list of things it can do..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-4950685187912165212?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/4950685187912165212/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=4950685187912165212' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/4950685187912165212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/4950685187912165212'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2008/01/using-apple-remote-in-boot-camp.html' title='Using Apple remote in Boot Camp'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-644865671480898672</id><published>2008-01-13T21:31:00.000+11:00</published><updated>2008-01-13T21:42:41.502+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mac'/><category scheme='http://www.blogger.com/atom/ns#' term='drivers'/><category scheme='http://www.blogger.com/atom/ns#' term='Boot Camp'/><title type='text'>Video driver for Boot Camp</title><content type='html'>I had issues with setting up an external monitor with any decent resolution (1024 x 768). Did some digging and found a whole world of drivers out there.&lt;br /&gt;&lt;br /&gt;My MacBook Pro uses a nVIDIA GeForce 8600M GT. M is for mobile.&lt;br /&gt;&lt;br /&gt;It turns out that the mobile edition of nVIDIA display technology is customised by the OEM (Apple in this case), and as such drivers are only released via them. That means when nVIDIA release a new driver, it has to go to Apple for QA, package, release. What are the chances of getting the latest driver? None. Also, what if Apple have not done something properly - eg. setup for external monitors?&lt;br /&gt;&lt;br /&gt;So, the solution is to grab the standard nVIDIA driver, and overlay a "modded INF" to open up the functionality of the driver. This allows it to work on mobile video hardware, and opens up greater functionality such as external monitor resolutions :)&lt;br /&gt;&lt;br /&gt;For me, this is a must for anyone running Boot Camp...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-644865671480898672?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/644865671480898672/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=644865671480898672' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/644865671480898672'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/644865671480898672'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2008/01/video-driver-for-boot-camp.html' title='Video driver for Boot Camp'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-8293458833215748122</id><published>2008-01-13T21:23:00.000+11:00</published><updated>2008-01-13T21:31:22.539+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Mac'/><category scheme='http://www.blogger.com/atom/ns#' term='Boot Camp'/><title type='text'>Experience with Boot Camp (Windows on Mac)</title><content type='html'>I've been using Boot Camp for six months or so now, after buying the wife a 17" MacBook Pro. I've now ventured into a 15" myself. Why?&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Apple hardware is very high spec (fast)&lt;/li&gt;&lt;li&gt;Industrial design is of a very high standard&lt;/li&gt;&lt;li&gt;It looks great&lt;/li&gt;&lt;/ul&gt;I found Bootcamp works pretty well with Vista on it, in all. In fact probably the best machine I've run Vista on! The only annoyance for a Windoze boy such as me was:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Getting used to the keyboard, but not a big deal. Keyboard is a lot more compact than the PC ones generally - just like a PC based laptop, just, different and a little quirky..&lt;/li&gt;&lt;li&gt;Runs VERY hot. The top surface is uncomfortable when it is doing a lot of work. Similarly when sitting on your lap.&lt;/li&gt;&lt;li&gt;Not massively mobile: MacBook Pro's are not known to be a featherweight, but you know that in advance. My inclination is towards power anyway...&lt;/li&gt;&lt;li&gt;Video drivers are pretty limited / old? More on this later..&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;For the record I've booted OS X twice - once for each, in order to then run Boot Camp. I have no time for OS X - so shoot me.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-8293458833215748122?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/8293458833215748122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=8293458833215748122' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/8293458833215748122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/8293458833215748122'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2008/01/experience-with-boot-camp-windows-on.html' title='Experience with Boot Camp (Windows on Mac)'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-1626887981139483395</id><published>2008-01-02T12:14:00.000+11:00</published><updated>2008-01-02T12:19:35.158+11:00</updated><title type='text'>Great speaker sound dampning enclosures</title><content type='html'>I found these at CEDIA07 in QLD: DYNAMAT wrap-arounds for in-wall speakers, plus boxes to sit over the top of in-ceiling speakers. A whole bunch of other materials for pre-gyprock preparation too. The speaker boxes are quite incredible in preventing noise escaping above into the ceiling space (and therefore throughout the house)..&lt;br /&gt;&lt;br /&gt;Supplied in Australia by &lt;a href="http://www.audioxtra.com.au/?pageId=2991&amp;amp;categoryId=2379"&gt;AudioXtra&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-1626887981139483395?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/1626887981139483395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=1626887981139483395' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/1626887981139483395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/1626887981139483395'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2008/01/great-speaker-sound-dampning-enclosures.html' title='Great speaker sound dampning enclosures'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-133429609398595808</id><published>2007-09-13T09:40:00.001+10:00</published><updated>2007-09-13T09:42:37.652+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>Heap Corruption</title><content type='html'>I did not find much mention of the following error that was plagueing me:&lt;br /&gt;&lt;br /&gt;Critical error detected c0000374&lt;br /&gt;&lt;br /&gt;This is a generic heap corruption error, but the trick is that it is COM's heap that it stores BSTR's in that was the issue - not the traditional CRT heap that all the references will lead you towards.&lt;br /&gt;&lt;br /&gt;There seemed to always be corrupt BSTR's being processed at the time. The answer was that I was SysFreeString'ing a BSTR and then keeping it around as if it were still a valid string.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-133429609398595808?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/133429609398595808/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=133429609398595808' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/133429609398595808'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/133429609398595808'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2007/09/heap-corruption.html' title='Heap Corruption'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-3551067593801138892</id><published>2007-07-08T22:27:00.000+10:00</published><updated>2007-07-08T22:33:45.271+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Center'/><category scheme='http://www.blogger.com/atom/ns#' term='InFusion'/><category scheme='http://www.blogger.com/atom/ns#' term='Home Automation'/><category scheme='http://www.blogger.com/atom/ns#' term='Vantage'/><title type='text'>Vantage InFusion: Under the software hood</title><content type='html'>&lt;p&gt;I’ve been doing a lot of work in extending the InFusion product, since even though it is the most advanced home automation control system around – as a programmer I find it extremely limiting. My extensions are intended to make it a little less so.&lt;br /&gt;&lt;br /&gt;I have written a software package called ‘VertigoTools’ which consists of a software installer that takes a bunch of InFusion Design Center procedures and third party objects; and installs them into an existing Design Center installation.&lt;br /&gt;&lt;br /&gt;It performs this by modifying a bunch of system files used, and adding some new ones as well. Don’t worry – any additions to the system are clearly marked in the XML data as being from the VertigoTools so there is no confusion.&lt;br /&gt;&lt;br /&gt;The following functionality is added:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;New Data type: Decimal; allows variables to store fixed-point values&lt;/li&gt;&lt;li&gt;New Objects:&lt;br /&gt;o   AnalogueInput: represents an analogue input channel&lt;br /&gt;o   ADAM-6017: driver for an 8-channel analogue input station, that connects via TCP/IP.&lt;/li&gt;&lt;li&gt;New Procedures:&lt;br /&gt;o   Three Speed Fan Control: controls a multi-speed fan that have a three-leg fan capacitor (eg. &lt;a href="http://www.hunterpacific.com.au/product_detail_pages/concept2.html"&gt;Hunter Pacific Concept2&lt;/a&gt;) . LED output is provided to indicate Off/Low/Med/High with light intensity.&lt;br /&gt;o   Light and Fan Motion Sensor: a combination of light-and-fan, and motion sensor functionality into a single procedure! The functionality provided by this procedure cannot be matched by a custom task.&lt;br /&gt;o   Set String From Variable: sets a LCD status text field to the value contained in a variable. Allows for Decimal data type, as well as optional formatting features such as trailing-zero truncation, thousands separators, and a special invalid value.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This is only the beginning, there is plenty of scope for improvement/extension. With the upcoming release of Design Center 2.0, who knows what will be possible.&lt;br /&gt;&lt;br /&gt;Coming up: a new programming model for home/building automation.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-3551067593801138892?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/3551067593801138892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=3551067593801138892' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/3551067593801138892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/3551067593801138892'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2007/07/vantage-infusion-under-software-hood.html' title='Vantage InFusion: Under the software hood'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-4544059844616886512</id><published>2007-07-08T22:24:00.000+10:00</published><updated>2007-07-08T22:27:36.599+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Parallels'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac'/><category scheme='http://www.blogger.com/atom/ns#' term='Vista'/><category scheme='http://www.blogger.com/atom/ns#' term='Boot Camp'/><title type='text'>Parallels and Boot Camp</title><content type='html'>I did something unthinkable. I got a &lt;a href="http://www.apple.com/au/macbookpro/"&gt;Mac&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;At the risk of offending those other (other?) faith, I find it a great machine to run Vista. Now I have got everyone offside.&lt;br /&gt;&lt;br /&gt;I tried running &lt;a href="http://www.parallels.com/"&gt;Parallels &lt;/a&gt;and &lt;a href="http://www.apple.com/bootcamp/"&gt;Boot Camp &lt;/a&gt;as options to running Vista on my Mac.&lt;br /&gt;&lt;br /&gt;Parallels is a very smart virtualisation product, that emulates the notion of integrating Windows® windows into the OS X® desktop (“coherence”). You get the giddying feeling of world unification to see the two worlds unite – but there is some smoke-and-mirrors involved. The Vista desktop runs “off screen” and targeted sections of the desktop (relating to your apps) are replicated onto the OS X desktop. Very cool – but you do see some visual artifacts when you drag windows around. I don't think virtualisation can get much better.&lt;br /&gt;&lt;br /&gt;Boot Camp is a set of Windows® drivers for Mac hardware. Enough said, that’s all there is really. I have not booted OS X since I installed Vista. The hardware performs really well for Vista (latest MacBook Pro), so no complaints there. The only issue is the keyboard layour – oh and the lack of PCMCIA slots.&lt;br /&gt;&lt;br /&gt;My pick: Boot Camp, unless you really are confused and use both OS’s all day long. Parallels is cute, but for power users any form of virtualisation is just a “go slow” layer.&lt;br /&gt;&lt;br /&gt;Got to hand it to Apple – they design really well. Just a pity they aren’t in the software business.&lt;br /&gt;&lt;br /&gt;For the record, I still have OS X on there for the future if I discover something I need it for (I’m told video editing is much better).&lt;br /&gt;&lt;br /&gt;Tip: I use a Wireless Mighty Mouse, when bringing the MacBook Pro back from slumber I need to revive the mouse. This is done by pressing the ‘nipple’ (you know what I mean..) a few times. Or else you can delete and re-associate the Bluetooth® device if you like to do things the hard way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-4544059844616886512?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/4544059844616886512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=4544059844616886512' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/4544059844616886512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/4544059844616886512'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2007/07/parallels-and-boot-camp.html' title='Parallels and Boot Camp'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-7758800292652455396</id><published>2007-06-20T13:06:00.000+10:00</published><updated>2007-06-20T13:24:29.849+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='view performance'/><category scheme='http://www.blogger.com/atom/ns#' term='SUSER_SNAME'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><title type='text'>SQL Server performance on SUSER_SNAME() joins</title><content type='html'>I came across a painful &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;performance&lt;/span&gt; issue with merge replication on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;SQL&lt;/span&gt; 2000. OK - it is a &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_2"&gt;temperamental&lt;/span&gt; beast, but the performance we were seeing was so bad - way too bad.&lt;br /&gt;&lt;br /&gt;After digging through the system generated views, the root cause came down to using SUSER_SNAME() in WHERE clauses as part of table joins. Replacing the function with a constant literal solved the problem.&lt;br /&gt;&lt;br /&gt;Take the following system-generated replication view:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;ALTER VIEW [Perm_VIEW] AS&lt;br /&gt;  SELECT DB.*&lt;br /&gt;    FROM DB JOIN Perm ON DB.DBID=Perm.DBID&lt;br /&gt;    WHERE Perm.UserName=SUSER_SNAME() and ({ fn ISPALUSER('1A9E41A4-55B9-0E55-ACD6-4CC0B419BDE0') } = 1)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;.. now, SUSER_SNAME() you would think would operate as if it were a constant string. I mean, it can't change during execution or anything - so you wouldn't go re-evaluating it for every row. That's exactly what it does - as if it were constantly changing the return value.&lt;br /&gt;&lt;br /&gt;The problem is that SUSER_SNAME() is desigated as "non-deterministic" by SQL Server. It kind of is, and kind of isn't. What the SQL Server team were thinking that it is non-deterministic between users, but it is obviously deterministic for a single user (and therefore query execution).&lt;br /&gt;&lt;br /&gt;SUSER_SNAME() is deemed as a fairly unreliable "unknown quantity" that it must guess the reliability of, the opposite of what it is - a very reliable item to query on.&lt;br /&gt;&lt;br /&gt;So, the standard recommendation is to put the result in a variable, and then use that. Duh. Works fine if you are in a stored proc, but less practical in a VIEW. After much research, here is the simplest/most elegant solution:&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;ALTER VIEW [Perm_VIEW] AS&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;  SELECT DB.*   &lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;    FROM DB JOIN Perm ON DB.DBID=Perm.DBID&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;    WHERE Perm.UserName=&lt;strong&gt;&lt;span style="color:#cc0000;"&gt;(SELECT&lt;/span&gt;&lt;/strong&gt; SUSER_SNAME()&lt;span style="color:#cc0000;"&gt;)&lt;/span&gt; and ({ fn ISPALUSER('1A9E41A4-55B9-0E55-ACD6-4CC0B419BDE0') } = 1)&lt;/span&gt; &lt;/p&gt;This gives SQL help by forcing it to use only a single value returned by the function, that it does not need to re-evaluate. The impact on this performance improvement will vary, but I saw betwen 6-17x improvements in performance. In particular eliminating Index/Table Scans, and making it able to use Seeks instead.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-7758800292652455396?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/7758800292652455396/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=7758800292652455396' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/7758800292652455396'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/7758800292652455396'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2007/06/sql-server-performance-on-susersname.html' title='SQL Server performance on SUSER_SNAME() joins'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-6547510789732179923</id><published>2006-12-06T13:50:00.000+11:00</published><updated>2006-12-06T15:43:58.612+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Design Center'/><category scheme='http://www.blogger.com/atom/ns#' term='InFusion'/><category scheme='http://www.blogger.com/atom/ns#' term='Home Automation'/><category scheme='http://www.blogger.com/atom/ns#' term='Vantage'/><title type='text'>Vantage InFusion Design Center software</title><content type='html'>It has been 48 hours since I got a copy of &lt;a href="http://www.vantagecontrols.com/"&gt;Vantage&lt;/a&gt; &lt;a href="http://www.vantagecontrols.com/products/software/designcenter/"&gt;Design Center&lt;/a&gt; software. My house recently completed construction, and &lt;a href="http://www.aaav.com.au/"&gt;All About A/V&lt;/a&gt; arranged for the install of a &lt;a href="http://www.vantagecontrols.com/products/Product.asp?id=90"&gt;InFusion&lt;/a&gt;-based home automation system. To give you an idea of the scope of this system, it contains x dimmer and y relay circuits under InFusion control. It is the first installation of InFusion in Australia.&lt;br /&gt;&lt;br /&gt;As a programmer by trade, I was naturally keen (insisting?) on getting access to the design software. I was not disappointed.&lt;br /&gt;&lt;br /&gt;My background is a software architect and programmer of more corporate enterprise software (Windows / .NET), instead of hardware-based stand-alone systems such as home automation. In my blog I want to capture all the things I learn along the way, from the perspective of an application software developer.&lt;br /&gt;&lt;br /&gt;First impressions as such that InFusion is a very stable platform – I have not seen any evidence of instability or unreliability – which is a must for home automation. I am not sure what operating system InFusion uses, but it looks a little Linux-esque. I haven’t looked into this any further – but I must say I am pretty happy it does not run Wintel. Ouch.&lt;br /&gt;&lt;br /&gt;In the surface InFusion is a little black box (blue actually) that does stuff. It has no UI of any significance, but is a control system that does things in response to external events (buttons, switches, movement detectors, temperature, light, clock etc.). It has USB and Ethernet interfaces. DHCP or static IP – no matter. For the record, I am waiting until the DIN controller is released, until then I am using a "borrowed" controller.&lt;br /&gt;&lt;br /&gt;What the Design Center gives you is the ability to program the InFusion Controller to do some sophisticated stuff. While it is pretty light in terms of pure programming per se, it hits a broad appeal by giving people who are not veteran programmers the ability to create powerful control scenarios. There will always be pressure to dumb-down or smarten up a tool such as this, but I think Vantage have done a pretty good job at getting decent spread of target skills in the tool they have provided. Being .NET based, using lots of XML under the covers, with a modern UI helps as well. I think the team at Vantage did a great job at representing really well the power of InFusion.&lt;br /&gt;&lt;br /&gt;Having said all this, there will be lot of trial and error in getting this all to work properly mainly because there is such a broad spectrum of Design Center users. On the one hand I think the task is a hard one for non-programmers since people do not naturally think logically/procedurally, but as a programmer it is taking me a while to find out exactly where the level of sophistication lies in the design. Here is what I have learned:&lt;br /&gt;&lt;u&gt;&lt;/u&gt;&lt;br /&gt;&lt;u&gt;Terms&lt;/u&gt;&lt;br /&gt;&lt;u&gt;&lt;/u&gt;&lt;br /&gt;Here are the really important terms in the context of InFusion/Design Center:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Loads: lights, or anything that consumes power&lt;/li&gt;&lt;li&gt;Procedures: pre-defined pieces of functionality&lt;/li&gt;&lt;li&gt;Tasks: created in Design Center to tie together procedures with conditional logic.&lt;/li&gt;&lt;li&gt;Areas: a fairly arbitrary hierarchy of buildings/floors/rooms etc. used to organise all your loads&lt;/li&gt;&lt;/ul&gt;Tasks are pretty simple from a programmer's viewpoint. Here are the key points I learned early on which I needed before I could understand how it would work:&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Blocking&lt;/u&gt;&lt;br /&gt;&lt;u&gt;&lt;/u&gt;&lt;br /&gt;Task steps are blocking - take the following task steps:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_HTwXUx7arM0/RXY0aGGYZDI/AAAAAAAAAAU/tM7UqdtKIEs/s1600-h/task.GIF"&gt;&lt;img id="BLOGGER_PHOTO_ID_5005245658787505202" style="CURSOR: hand" alt="" src="http://1.bp.blogspot.com/_HTwXUx7arM0/RXY0aGGYZDI/AAAAAAAAAAU/tM7UqdtKIEs/s400/task.GIF" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Contrary to popular belief, the Motion Sensor procedure above will prevent execution of any subsequent steps until it has completed. That means in the case of Motion Sensor that the light has come on, the Off Delay time has passed, and the load has been turned off. It is not the case that subsequent steps in the task will continue, along with the Motion Sensor in parallel. So that means the log entry 'Test 2' happens after the light goes out. Initially I had been told that they were executing in parallel (in layman's terms), which scared the heck out of me, since the implications of that are.. well.. dangerous!&lt;br /&gt;&lt;br /&gt;To take an old favourite, I have seen a sensor/light/fan task designed as below. This task is to turn on a fan according to a sensor, but delay the fan until the light has been on for a period of time (eg. 25 seconds), then run the fan for another period (eg. 1 min) beyond when the light is switched off.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/_HTwXUx7arM0/RXYxMWGYZCI/AAAAAAAAAAM/oZr_CRMcRbY/s1600-h/task.GIF"&gt;&lt;img id="BLOGGER_PHOTO_ID_5005242124029420578" style="CURSOR: hand" alt="" src="http://2.bp.blogspot.com/_HTwXUx7arM0/RXYxMWGYZCI/AAAAAAAAAAM/oZr_CRMcRbY/s400/task.GIF" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Taking the steps one at a time (in a blocking manner) we can see the above does not do what is expected:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;The light comes on, and turns off according to the Motion Sensor procedure (ie. someone has left the room)&lt;/li&gt;&lt;li&gt;Nothing. The if statement tests if the light is off - it "always" is at this point since the Motion Sensor procedure would have already turned it out. In any case &lt;em&gt;there is no code to run as a consequence&lt;/em&gt; as there is no indented steps after this if statement.&lt;/li&gt;&lt;li&gt;Wait 25 seconds&lt;/li&gt;&lt;li&gt;Turn on the fan&lt;/li&gt;&lt;li&gt;Nothing. The if statement tests if the light is off - it still is. This time there are steps indented below, so they will run.&lt;/li&gt;&lt;li&gt;Wait 1 minute&lt;/li&gt;&lt;li&gt;Turn off fan&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;So instead of the intended behaviour, you get instead: light on, light off, delay, fan on, delay, fan off. The confusion here was the belief that the Motion Sensor procedure was not blocking, so the delays and fan load changes would happen while the light was on.&lt;/p&gt;&lt;u&gt;No flow control&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;One annoyance is the lack of real flow control, beyond basic 'if' statements in tasks. The lack of loops/while statements etc. keeps it simple for the masses - but there are now many things I think I need to dig in deeper for. On the up-side, there are no infinite loops! Simple ones at least anyway...&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Enhancements/Bugs?&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Don’t provide warnings for task steps that are disabled&lt;/li&gt;&lt;li&gt;Associate dry contact inputs with Areas – it is less convenient to find these things in the dimmer, rather than the location of the PIR etc. &lt;/li&gt;&lt;li&gt;Provide some descriptions for the properties of Dry Contacts. One of the few areas where good descriptions are not found &lt;/li&gt;&lt;li&gt;Provide a warning for task steps which are redundant - eg. an if statement with no indented target steps&lt;/li&gt;&lt;li&gt;View the underlying .amx scripts generated by tasks&lt;/li&gt;&lt;li&gt;Write custom .amx/.sma procedures, and be able to construct 3rd party libraries of such&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;u&gt;Questions I Have&lt;/u&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Can I attach tasks to load events?&lt;/li&gt;&lt;li&gt;Can I write my own procedures in .SMA scripts as the software currently stands? ie. create now own .SMA file and edit the LibraryInformation.xml to link it in. Will this automatically be deployed to my Controller by the software?&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-6547510789732179923?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/6547510789732179923/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=6547510789732179923' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/6547510789732179923'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/6547510789732179923'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/12/vantage-infusion-design-center-software.html' title='Vantage InFusion Design Center software'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_HTwXUx7arM0/RXY0aGGYZDI/AAAAAAAAAAU/tM7UqdtKIEs/s72-c/task.GIF' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-3725258440292664815</id><published>2006-12-06T11:57:00.000+11:00</published><updated>2006-12-06T15:39:38.932+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PDF'/><category scheme='http://www.blogger.com/atom/ns#' term='PdfCompressor'/><category scheme='http://www.blogger.com/atom/ns#' term='JBIG2'/><category scheme='http://www.blogger.com/atom/ns#' term='compression'/><title type='text'>PDF Goes on a Diet</title><content type='html'>I have been doing a lot of work on PDF formats – something which I have taken for granted up until this stage.&lt;br /&gt;&lt;br /&gt;One point of interest is the development of JBIG2 – an image compression standard, which focuses on scanned text images. Since this is the type of content I am dealing with, it is a perfect match.&lt;br /&gt;&lt;br /&gt;Essentially, JBIG2 aims to replace TIFF (in its various forms) for fax-style content. It works by recognising characters in the pages, and representing that, in addition to non-character based content. Essentially this gets a PDF with scanned pages in it, down to a similar size to as if it had been natively produced in a PDF – in the order of 10x compression. In effect it compresses a scanned page in PDF form down to the size of the raw document (eg. Word .DOC) used to produce it.&lt;br /&gt;&lt;br /&gt;Nice.&lt;br /&gt;&lt;br /&gt;The best commercial product to do all this I found was &lt;a href="http://www.cvisiontech.com"&gt;CVista PdfCompressor&lt;/a&gt; - very flexible licensing, and produced the best results in real-world testing for me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-3725258440292664815?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/3725258440292664815/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=3725258440292664815' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/3725258440292664815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/3725258440292664815'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/12/pdf-goes-on-diet.html' title='PDF Goes on a Diet'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-3013817793390801070</id><published>2006-10-19T10:25:00.000+10:00</published><updated>2006-10-24T15:35:16.044+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='IceTV'/><category scheme='http://www.blogger.com/atom/ns#' term='Nine'/><title type='text'>Nine v IceTV court case</title><content type='html'>With the current movements in the media industry, most have not yet heard of a low profile case working its way through the Federal Court in Australia. It is between the nations most aggressive TV network - &lt;a href="http://www.nine.com.au"&gt;Channel Nine&lt;/a&gt; - and a small &lt;a href="http://en.wikipedia.org/wiki/Electronic_program_guide"&gt;EPG&lt;/a&gt; provider - &lt;a href="http://www.icetv.com.au/"&gt;IceTV&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;You can check out more on the background to this case &lt;a href="http://www.pcworld.idg.com.au/index.php/id;1784690620"&gt;here&lt;/a&gt;, but I love the quote from the chairman of IceTV:&lt;br /&gt;&lt;br /&gt;"[It is] like Australia Post suing Microsoft for inventing the email,"&lt;br /&gt;&lt;br /&gt;I think this quote (which probably came from founder &lt;a href="http://www.anerd.com/"&gt;Peter Vogel&lt;/a&gt;) really sums up the case. Nine are suing IceTV on the basis that using the program guide, describing what TV shows are playing when on Nine, infringes their copyright - since they publish the guide. That's it. IceTV claim they have a part-automated, part-journalism process that creates the guide without copying the guide published by Nine.&lt;br /&gt;&lt;br /&gt;I think there are some great areas for IceTV to move in the future:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Publishing an after-the-case guide, eg. providing a summary of TV shows that have already aired. eg. I am looking at ABC "7:30 report" in my EPG, not knowing if I really want to watch it. I notice in the review that there was a last-minute interview with a leader from North Korea about their nuclear testing, that I am interested in, so I decide to watch it.&lt;/li&gt;&lt;li&gt;Providing advertising that people actually want to watch; specific targeted advertising. I do find using an EPG, that I sometimes do rewind to specifically watch an ad I am interested in. 95% however, I am not.&lt;/li&gt;&lt;li&gt;Real-time EPG, taking into consideration the usual game playing that free-to-air channels use to make sure you cannot transition easily from one channel to another in prime time. If you haven't noticed, channels on occasion begin and end at different times to those advertised. A real-time EPG could work around this by actually having people watching and adjusting as it happens.&lt;/li&gt;&lt;/ul&gt;If Nine succeeds by bleeding IceTV of its cash, they will have been victorious in plugging the dyke for a little longer, and keeping this country back from the evolution of public media. No wonder viewership is falling.&lt;br /&gt;&lt;br /&gt;My take on it is a classic case of a 1980's media organisation, which has been used to being propped up by government protection its whole life, is now under threat from technology. While Nine was happy to collaborate with Microsoft on the ninemsn venture, Microsoft were interestingly unable to launch a free EPG for their products, as they have done in the US.&lt;br /&gt;&lt;br /&gt;Keep your friends close, and your enemies closer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-3013817793390801070?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/3013817793390801070/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=3013817793390801070' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/3013817793390801070'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/3013817793390801070'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/10/nine-v-icetv-court-case.html' title='Nine v IceTV court case'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114985626787232405</id><published>2006-06-09T22:31:00.000+10:00</published><updated>2006-12-06T15:40:02.847+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='streaming'/><category scheme='http://www.blogger.com/atom/ns#' term='dynamic'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><title type='text'>Dynamic/Streaming XML Data</title><content type='html'>Up until now XML data has been fairly static and boring. Without wanting to get bogged down in too much philosophical naval-gazing on the subject, for me an oddity in the evolution of XML was the creation of &lt;a href="http://www.mddl.org/"&gt;MDDL&lt;/a&gt; (Market Data Definition Language) – as financial market data was the area I was working in at the time. The most important and complex systems with market data are ones that require high performance, and dynamic/streaming updates. XML is incapable of delivering this. Of course MDDL is useful for more consumer-oriented "snap-shot stock quote" solutions, but for me the more important applications were being neglected.&lt;br /&gt;&lt;br /&gt;To retrofit XML into to dynamic/streaming data world (see my &lt;a href="http://www.vertigotechnology.com/terminology.aspxhttp:/www.vertigotechnology.com/terminology.aspx"&gt;definitions page&lt;/a&gt; on the confusion over these terms), extra smarts are required. We just don’t have the pieces necessary right now to make this work. Here's a &lt;a href="http://www.google.com.au/search?q=mddl+dynamic+streaming+data&amp;hl=en&amp;amp;lr=&amp;rls=GGLG,GGLG:2005-51,GGLG:en&amp;amp;start=10&amp;sa=N"&gt;great presentation&lt;/a&gt; from FISD on the scope of the problem, and a bit of a review of the available solutions. One solution is the approach taken by &lt;a href="http://xml.coverpages.org/ni2003-12-19-a.html"&gt;fisdMessage&lt;/a&gt;, which essentially works by updating values within an existing XML document (such as MDDL). No structural changes to the XML document are possible with updates (the theory being that this is not desired anyway, as this type of data is fairly homogenised).&lt;br /&gt;&lt;br /&gt;While right now it is true that financial data is homogenised to the point that the structure of the data does not change in a fluid matter; but possibly this is a short-term (and dare I say US-centric) view? It is my feeling that the reason the data is currently quite static in structure is because of technology limitations, rather than preference. With current day non-XML technology it is far more difficult to achieve dynamic structural changes – so they are rarely implemented.&lt;br /&gt;&lt;br /&gt;XML is very good at handling structure; my belief is that we want to preserve this capability in as many ways as we can. We do not want to throw this away, unless we have no other choice.&lt;br /&gt;&lt;br /&gt;In thinking about how to implement dynamic/streaming data using XML led me to design a complementary technology that allowed the familiar and open XML model to be used for dynamic applications. Not financial prices, but all data. The scope of my investigation was:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;XML centric: all data content is assumed to be available in, and consumed in, XML form.&lt;/li&gt;&lt;li&gt;Large: the underlying content contains medium to large datasets (1,000's of items).&lt;/li&gt;&lt;li&gt;Fluid: the content is changing regularly, both in content and structure.&lt;/li&gt;&lt;li&gt;Timely: consumers of content are interested in seeing the very latest information.&lt;/li&gt;&lt;li&gt;Resilient: bandwidth varies in availability, and should handle periods of low availability.&lt;/li&gt;&lt;li&gt;Efficient: able to be implemented on the client, with a minimal footprint.&lt;/li&gt;&lt;/ul&gt;The above could apply equally to: online forums, sport scores, news websites.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;&lt;strong&gt;A Review of XML Technology&lt;/strong&gt;&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;A series of technologies come to mind when thinking of handling changing XML documents: XyDelta, DeltaXML™, XML Diff Language (Microsoft) to name a few. However these were trying to solve a different problem set. They were focused on more static document-based content, where updates were more infrequent, and were not going to be distributed in a time-critical manner. They were more about efficiency, reducing the amount of data traffic when doing substantial chunky mods to existing documents. In addition, they were generally produced by comparing two versions of a document, rather than by the atomic events that caused their changes.&lt;br /&gt;&lt;br /&gt;To be continued…&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114985626787232405?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114985626787232405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114985626787232405' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114985626787232405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114985626787232405'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/06/dynamicstreaming-xml-data.html' title='Dynamic/Streaming XML Data'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114966127925783276</id><published>2006-06-07T16:21:00.000+10:00</published><updated>2006-10-12T21:10:50.283+10:00</updated><title type='text'>VirtualArray: powerful data structure for large, fluid datasets</title><content type='html'>On my investigations into using XML for large datasets of rapidly changing data, I came across a performance issue to do with XML DOM implementations. If you want to find a given node in the node-list (ie. find its index) there is no scalable way to go since the DOM works via linked-lists. You have to “walk the DOM” in order to find the node you are looking for; keeping count of the number of siblings you step over in the process.&lt;br /&gt;&lt;br /&gt;Because MotionSet™ works in an event-based manner, a bottleneck occurs when working out the position of a given change. This task requires that the node’s index be determined, so it can be integrated into the existing delta. For example:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#666666;"&gt;&amp;lt;root&amp;gt;&lt;br /&gt;  &amp;lt;data1/&amp;gt;&lt;br /&gt;  &amp;lt;data2/&amp;gt;&lt;br /&gt;&lt;strong&gt;  &amp;lt;data2A/&amp;gt;&lt;em&gt; &lt;/em&gt;&lt;/strong&gt;&lt;em&gt;&lt;== this is going to be deleted&lt;/em&gt;&lt;br /&gt;  &amp;lt;data3/&amp;gt;&lt;br /&gt;&amp;lt;/root&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;An event is fired deleting the ‘data2A’ element, causing MotionSet™ to determine the index of the new node. In this case the zero-based index is 2. This leads to a delta from the parent node "root" of:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#666666;"&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;skip count="2"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;delete/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;At the moment, the only way to determine the index of a node is to do a brute-force linear search through all the children. Fine for reasonably sized datasets, but not good news for anything in the order of 1,000's of items.&lt;br /&gt;&lt;br /&gt;What is needed is a data structure, and relevant processes, that satisfy the following requirements:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;An ordered array of items: ie. order is important, and must be preserved. For example, it cannot be sorted to aid in searching.&lt;/li&gt;&lt;li&gt;Items can be obtained by index, as is normally the case in arrays&lt;/li&gt;&lt;li&gt;Index can be obtained by searching by item&lt;/li&gt;&lt;li&gt;Items are regularly being inserted, changed and deleted from the array&lt;/li&gt;&lt;/ul&gt;The classic approach would be to use a standard array, and build a hash-table (index) that converted the item value to an index value. The disadvantage with this is that, on average, 50% of the indexes will change in the case of an insert or delete. This means the hash-table needs to be regenerated after each insert or delete, with the inevitable performance penalty.&lt;br /&gt;&lt;br /&gt;What emerged (dubbed "VirtualArray") is an array that satisfies all the above.&lt;br /&gt;&lt;br /&gt;VirtualArray consists of two data structures:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;A modified form of binary tree: this is used to store the data items in a sorted manner, sorted on the index of each item in the VirtualArray. This can be any form of tree-like structure, but personally I like &lt;a href="http://en.wikipedia.org/wiki/Red-black_tree"&gt;red-black tree&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A hash-table to provide access to a given tree node (see above), by item in the VirtualArray. This can be a simple sorted list in hash order, using binary-search.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The tree is modified in a way that assists in adjusting the indexes of items subsequent to deleted/inserted items in the VirtualArray. This is performed by storing relative index values at each node, rather than absolute ones. To calculate an actual index for a node, all the ancestor nodes in the tree are added together. By calculating the index in this fashion, the number of nodes that need to have their relative index adjusted after an insert/delete is very limited. The down-side is that index values are not readily available, but must be calculated at each point – but given the characteristics of appropriate tree-like structures, this is still very scalable.&lt;br /&gt;&lt;br /&gt;So what does this all look like in reality? I implemented a series of tasks, using a set of different storage techniques:&lt;br /&gt;&lt;br /&gt;Tasks:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Look up a value by (random) index&lt;/li&gt;&lt;li&gt;Look up the index for this value&lt;/li&gt;&lt;li&gt;Remove an item by (random) index&lt;/li&gt;&lt;li&gt;Insert a new item into a (random) index&lt;/li&gt;&lt;li&gt;Update an existing item by (random) index&lt;/li&gt;&lt;/ol&gt;Granted, the steps are skewed to the particular requirements we are interested in, so it comes as no surprise the performance is so bad for the non-VirtualArray techniques:&lt;br /&gt;&lt;br /&gt;Techniques: (.NET 2.0 types)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;List&amp;lt;XmlNode&amp;gt; (simple array)&lt;/li&gt;&lt;li&gt;LinkedList&amp;lt;XmlNode&amp;gt; (simple linked list) &lt;/li&gt;&lt;li&gt;XmlNodeList&lt;/li&gt;&lt;li&gt;VirtualArray&amp;lt;XmlNode&amp;gt;&lt;/li&gt;&lt;li&gt;XLinq (coming soon!)&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;By measuring the average total time taken to perform the above tasks, using each technique, the following was the result:&lt;/p&gt;&lt;p&gt;&lt;a href="http://photos1.blogger.com/blogger/5275/1960/1600/image001.0.png"&gt;&lt;img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/5275/1960/400/image001.0.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Note that the X (size of array) and Y (time taken) are both log scales. You can see that the traditional techniques are roughly linear in performance (as expected), but they have better performance than VirtualArray for smaller arrays. As expected, XmlNode does not perform well with these tasks.&lt;br /&gt;&lt;br /&gt;To put this in perspective for those who don't get having a log scale on &lt;em&gt;both &lt;/em&gt;axes, the log scale has been removed from both axes below:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/5275/1960/1600/image003.0.png"&gt;&lt;img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/5275/1960/400/image003.0.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The sharp improvements in performance could be related to memory swapping, as they almost disappeared when I performed each technique's test in isolation. Below is a test comprising of only List&amp;lt;XmlNode&amp;gt; and VirtualArray&amp;lt;XmlNode&amp;gt;:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://photos1.blogger.com/blogger/5275/1960/1600/image005.png"&gt;&lt;img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/5275/1960/400/image005.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;.. and with the log scales re-applied:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/5275/1960/1600/image007.png"&gt;&lt;img style="CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/5275/1960/400/image007.png" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;From this chart, we can see that 1,000 items is where VirtualArray starts to outperform a simple array. From this, VirtualArray has been enhanced to use a simple array until the number of items reaches a set threshold (1,200). At this point the simple array data is copied into the tree/hash-table structures. If the number of items then falls below another threshold (600), the data is copied back into a simple array. This means that VirtualArray does not sacrifice performance in the lower end of the array sizes.&lt;br /&gt;&lt;br /&gt;What does this mean for the XML DOM? Well, in my view - not much for the current XML space.&lt;br /&gt;&lt;br /&gt;In order for you to believe that that there is a problem in need of a fix, you need to accept the following: &lt;/p&gt;&lt;ul&gt;&lt;li&gt;DOM collections (XmlNodeList) sizes in the 1,000's are a practical performance problem (most don’t go anywhere near this size)&lt;/li&gt;&lt;li&gt;Finding the index of a given node amongst its siblings is something you need to do. MotionSet™ needs this operation, but it's hardly a top-10 operation.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This investigation is taking XML/DOM into a space where it is not currently: large datasets of highly fluid, and constantly changing in-memory information. XML/DOM is currently more at home with medium-size static documents, and either generated on-demand or kept on permanent store.&lt;br /&gt;&lt;br /&gt;VirtualArray provides the necessary performance boost to handle large dynamically changing datasets.&lt;/p&gt;&lt;p&gt;Note: VirtualArray is patent pending technology.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114966127925783276?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114966127925783276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114966127925783276' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114966127925783276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114966127925783276'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/06/virtualarray-powerful-data-structure.html' title='VirtualArray: powerful data structure for large, fluid datasets'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114965986935161224</id><published>2006-06-07T15:52:00.000+10:00</published><updated>2006-10-12T21:10:50.222+10:00</updated><title type='text'>Patent application</title><content type='html'>A patent application has now been filed, convering a whole bunch of stuff I have been working on in the &lt;a href="http://www.vertigotechnology.com/superset.aspx"&gt;SuperSet&lt;/a&gt; space over the past months, but have been unable to talk/blog about. Time to lift the floodgates!&lt;br /&gt;&lt;br /&gt;For those of you that are interested in reading documents that look like they were written on a typewriter, you can view the &lt;a href="http://www.vertigotechnology.com/SuperSet-Spec.pdf"&gt;specification&lt;/a&gt;. Normally patent specifications don't get published for as long as they can get away with (at least 18 months), since people want to keep it secret, but not me!&lt;br /&gt;&lt;br /&gt;Please contact me if you wish to use the processes described, most of which I'll be posting about in this blog over the coming days. Of course my desire is to license the technology to others, and I plan to issue no-cost licenses to non-commercial projects. For what it is worth, this is not about &lt;a href="http://en.wikipedia.org/wiki/Patent_troll"&gt;patent troll&lt;/a&gt; tactics (this is our first patent application) – but instead having some form of protection over our technologies that copyright simply does not provide. For the record, we are building genuine commercial products from these technologies - this is not a plan to tax the innovative efforts of others.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114965986935161224?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114965986935161224/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114965986935161224' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114965986935161224'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114965986935161224'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/06/patent-application.html' title='Patent application'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114965934516944578</id><published>2006-06-07T15:49:00.000+10:00</published><updated>2006-10-12T21:10:50.158+10:00</updated><title type='text'>Empty XML Nodes</title><content type='html'>One annoyance I had with the DOM is that it did not collapse empty ones. That is:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#666666;"&gt;&amp;lt;root&amp;gt;&lt;br /&gt;     &amp;lt;a/&amp;gt;&lt;br /&gt;&amp;lt;/root&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;When 'a' was deleted became:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#999999;"&gt;&lt;span style="color:#666666;"&gt;&amp;lt;root&amp;gt;&lt;br /&gt;&amp;lt;/root&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;.. instead of just "&amp;lt;root/&amp;gt;".&lt;br /&gt;&lt;br /&gt;You may ask – "why do you care" – and that's a great question. In my case, I was comparing documents to see if they had changed back to where they started. If you were to compare a textual representation of the XML, this would fail since the "&amp;lt;root/&amp;gt;" != "&amp;lt;root&amp;gt;&amp;lt;/root&amp;gt;". Once great suggestion was from &lt;a href="http://blogs.msdn.com/mikechampion/"&gt;Michael Champion&lt;/a&gt; (MS) who suggested comparing &lt;a href="http://www.w3.org/TR/2001/REC-xml-c14n-20010315"&gt;Canonical XML&lt;/a&gt;. Why didn't I think of that?&lt;br /&gt;&lt;br /&gt;Anyway.. I wrote the following class to split out this optimization, since you need to be careful when you want to apply it. You use it by doing a:&lt;br /&gt;&lt;br /&gt;EmptyNodeOptimizer opt = new EmptyNodeOptimizer(xmlDocument);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#009900;"&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;public class EmptyNodeOptimizer&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    private XmlNodeChangedEventHandler _xmlNodeRemovedEvent;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    private XmlDocument _xmlDocument;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    public EmptyNodeOptimizer(XmlDocument doc)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        _xmlNodeRemovedEvent = new XmlNodeChangedEventHandler(XmlNodeRemovedEvent);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        Attach(doc);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    public void Attach(XmlDocument doc)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        // attach to document to optimise empty elements&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        _xmlDocument = doc;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        _xmlDocument.NodeRemoved += _xmlNodeRemovedEvent;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    public void Detach()&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        if (_xmlDocument != null)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;            _xmlDocument.NodeRemoved -= _xmlNodeRemovedEvent;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;            _xmlDocument = null;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    // Performs a cleanup of parent element when the last child is deleted&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    private void XmlNodeRemovedEvent(Object src, XmlNodeChangedEventArgs args)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        // does parent element now have no children?&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        if (args.OldParent != null &amp;&amp;amp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;            args.OldParent.NodeType == XmlNodeType.Element &amp;&amp;amp;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;            !args.OldParent.HasChildNodes)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;            // make sure it gets marked as empty&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;            (args.OldParent as XmlElement).IsEmpty = true;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;        }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    }&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114965934516944578?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114965934516944578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114965934516944578' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114965934516944578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114965934516944578'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/06/empty-xml-nodes.html' title='Empty XML Nodes'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114766463388469729</id><published>2006-05-15T13:43:00.001+10:00</published><updated>2006-10-12T21:10:50.034+10:00</updated><title type='text'>HTTP Resumability / Partial Downloads with ASP.NET</title><content type='html'>I have been looking for a way to support partial downloads (as IIS has done since 4.0 for files) with ASP.NET. Not an easy task since IIS must execute an ASPX page in order to get the content, it can’t just arbitrarily obtain subsections of the output as is required for range requests.&lt;br/&gt;&lt;br/&gt;The best solution I have seen (in the ASP.NET world) has been to implement a custom HttpHandler; this assumes you are getting your data from the file-system which can be randomly accessed. This provides a way to support download resumability on large files for which access is controlled by ASP.NET.&lt;br/&gt;&lt;br/&gt;&lt;a href="http://www.vbip.com/winsock/winsock_http_08_01.asp"&gt;http://www.vbip.com/winsock/winsock_http_08_01.asp&lt;/a&gt;&lt;br/&gt;&lt;br/&gt;(Health warning: code is written in VB)&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114766463388469729?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114766463388469729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114766463388469729' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114766463388469729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114766463388469729'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/05/http-resumability-partial-downloads.html' title='HTTP Resumability / Partial Downloads with ASP.NET'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114766458780047542</id><published>2006-05-15T13:43:00.000+10:00</published><updated>2006-10-12T21:10:49.974+10:00</updated><title type='text'>ASP.NET Data Binding</title><content type='html'>&lt;u&gt;Data updates fail in ASP.NET&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Problem: updates in a data binding scenario are not working – no errors, the data does not go through. On inspection (by trap the inserting event) the "Original_[key]" column has no value set.&lt;br /&gt;&lt;br /&gt;Solution: with your data viewing control (eg.  FormView) set the following attribute DataKeyNames="[KeyColumn1],[KeyColumn2]". For some reason these don’t come through (for me anyway) automatically when using the designer.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;ASP.NET Development&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;I am into building maintainable systems. Especially early in the dev cycle I am not into building mountains of repetitious code and stored procs. While they are great to have, changes inevitably cause you to re-work this early development anyway, no matter how hard you try to get the stars aligned before you start. At least I’ve never seen it work that way. This re-work is a significant cost that should be avoided if at all possible.&lt;br /&gt;&lt;br /&gt;For a piece of development I am looking at, I had the usual questions of architecture for an ASP.NET application. I looked at a bunch of approaches, but to be honest the full blown 3-tier/model-view-controller approach was not really an option. I did not have a team of devs to spend 50 hours a week grinding out the code, or the confidence that – after users actually used the system – there would not be significant changes to the fundamental model.&lt;br /&gt;&lt;br /&gt;So, my requirements were such that it needed to be very adaptable to changes, with a minimum of manual effort to change, say a column of a table which inevitably finds its way through to business objects and front-end code. Moving down the 3-tier/MVC approach would come with time, as I grew into it – with greater confidence that the fundamental model was solid.&lt;br /&gt;&lt;br /&gt;Remember, the worst thing that can happen in a development is – not that your model turns out to be a bit off, and you spend an extra 3-6 months converting the work you have already done; but instead that you live with it. This produces a system that does not match the way the users want it to work, and well.. that creates an ongoing cost.&lt;br /&gt;&lt;br /&gt;In this “agile”-ish mindset I investigated a number of techniques:&lt;br /&gt;&lt;br /&gt;&lt;u&gt;SqlDataSource Binding&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;Placing SqlDataSource items on the pages, and data binding from visual controls to those. This is effectively two-tier design, with all the pitfalls. More of an exercise really, this was really only appropriate in the most trivial of cases to act as a temporary measure before upgrading to something a bit better, like in 5 minutes time (read: prototype). The negative is a hit to the database, unless you activate the caching which I didn’t really look into. The idea of having a control on the visual design service directly bound to a SQL connection does not give me a good feeling.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Global DataSet&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;This technique involved designing a XSD DataSet using the visual designer, and keeping an instance in the global “Cache[]”. On first use this cache is created and pre-populated with the basic fundamental static data – eg. states, business rule tables etc. that in general do not change. This was enhanced with some SQL dependencies to ensure that when they are updated when the underlying data moved. No transactional information is kept here, just the stuff that may be changed once per week at the most. The advantage of this approach is you always have a ready supply of DataTable’s fully populated with the latest data. Then, when you come to drop visual controls – you can bind directly to these global DataTable’s, without the need to created, read, populate them as would normally be the case by using a DataSource. Of course this technique only works for data that is not customised on a per-user basis: or requires any level of sophisticated querying.&lt;br /&gt;&lt;br /&gt;This technique also allows you to easily make a copy of the global DataSet, giving you a pre-populated DataSet to modify, and then throw away.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;XSD DataSet Queries&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;The XSD was filled out with custom queries – embedded SQL where possible, or stored procs where some level of programmatic flow was required. I know this is not the best practice, but remember the goal here is to validate the design and user experience – I can always return to change the DataSet to call stored procs (and create more work for myself when things change) once the ground has firmed up.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Multiple Tables in DataSet&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;This technique I had to search for ages before I could work out how to get it to operate. The theory goes – I have a DataSet capable of storing data from several tables, and I want to display relational data from several tables. The DataSet provides excellent support for this – by allowing you to easily navigate child rows from related tables.&lt;br /&gt;&lt;br /&gt;So, I wanted to display multiple tables (using child GridView’s within parent GridView’s). The problem here is that the normal DataSet designer cannot handle (from what I can see) multiple resultsets from stored procedure calls, which is the normal technique of getting multiple tables from a SQL database.&lt;br /&gt;&lt;br /&gt;The way to do this requires you to abandon ObjectDataSource, and jump down one level to SqlDataAdapter. This allows you to provide a mapping between resultsets coming back from your stored procedure, and tables within your DataSet:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#333333;"&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;WidgetDataSet data = GlobalDataSetCopy();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;SqlDataAdapter a = new SqlDataAdapter();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;SqlConnection connection = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlDatabase"].ConnectionString);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;SqlCommand cmd = new SqlCommand();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;cmd.CommandText = "GetAllByWidgetId";&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;cmd.CommandType = CommandType.StoredProcedure;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;cmd.Connection = connection;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;cmd.Parameters.Add("@WidgetId", SqlDbType.UniqueIdentifier).Value = new Guid(Request["WidgetId"]);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;a.SelectCommand = cmd;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;a.TableMappings.Add("Table", "Widget");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;a.TableMappings.Add("Table1", "WidgetTitle");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;a.TableMappings.Add("Table2", "WidgetRole");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;a.TableMappings.Add("Table3", "WidgetDocument");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;a.Fill(data);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#333333;"&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;FormView1.DataSource = data.Widget;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;FormView1.DataBind();&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you look at the code generated by the XSD designer, you’ll see that this technique is actually used to map single resultsets to a specific table in the DataSet. As far as I can see there is no way to get it to support multiple resultsets – definitely a must for ASP.NET 3.0 I would think. The wizard could guide you through providing this mapping, meaning you could use the TableAdapter infrastructure for these types of queries.&lt;br /&gt;&lt;br /&gt;The above is a lot of work, and still leaves you with the issue of providing changes, since they must be handled separately via individual stored proc calls. More work in my view – especially in the early fluid period. It does however provide the best solution from a performance perspective, since a single round trip can handle large numbers of parent records, with all their various types of child records.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Binding DataSources to One Another&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;This can be enhanced by some very sophisticated data binding where you effectively bind a child ObjectDataSource to the child rows in the DataSet for the parent ObjectDataSource. It looks a bit ugly, but it effectively allows you to put a Repeater within a GridView column; which is very useful:&lt;br /&gt;&lt;br /&gt;eg.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;color:#333333;"&gt;&amp;lt;asp:Repeater ID="orders" DataSource='&amp;lt;%# ((DataRowView)Container.DataItem).CreateChildView("CustomerOrders")%&amp;gt;' Runat="server"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;See &lt;a href="http://www.codeproject.com/aspnet/Mastering_DataBinding.asp"&gt;http://www.codeproject.com/aspnet/Mastering_DataBinding.asp&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Completely Seperate ObjectDataSource’s&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;The advantage of using multiple ObjectDataSource’s (over multiple resultsets and custom SqlDataAdapter) is that all the insert/update/delete operations are handled in a unit – you don’t need to worry about them separately. The disadvantage is that there is a round-trip to the database for every parent record, and for each type of child records. Something you need to weigh up depending on the application.&lt;br /&gt;&lt;br /&gt;For me, the performance hit at runtime does not outweigh the implementation overhead, and besides I can always convert back to the more convoluted method should the need arise. Rearranging the DataSource’s does not involve messing up the visual controls since they are abstracted by the interface they supply. It also opens up the possibility I could create real business objects, instead of the ones supplied by the XSD designer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114766458780047542?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114766458780047542/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114766458780047542' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114766458780047542'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114766458780047542'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/05/aspnet-data-binding.html' title='ASP.NET Data Binding'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114766453706801867</id><published>2006-05-15T13:42:00.000+10:00</published><updated>2006-10-12T21:10:49.915+10:00</updated><title type='text'>EPIRB and PLB's: emergency transmitters</title><content type='html'>A few weeks ago I went on a mountain bike ride (28K or so) into Kangaroo Valley, a couple of hours south of Sydney. One guy had a really bad stack, severing all the tendons in his shoulder. We were a bit concerned about other injuries (crushed hand, bruising all over etc.) and one person in our party considered using his "EPIRB". I had never heard of one.&lt;br/&gt;&lt;br/&gt;Basically, it's a distress signal that means that emergency service professionals know you need help, if you're in a seriously bad situation with no alternative. As it turned out, we were able to walk him out (3KM or so) and National Parks drove him to hospital.&lt;br/&gt;&lt;br/&gt;Anyway...&lt;br/&gt;&lt;br/&gt;This lead me to investigate this “EPIRB” thing, how it worked etc. and this is what I found out. Analogue EPIRB’s (~$300) are single-use devices that transmit a signal on a known emergency frequency. This allows you to be detected and tracked by satellites and aircraft as they try to find you. Here’s how the process works:&lt;br/&gt;&lt;br/&gt;&lt;ul&gt;&lt;li&gt;Between 30mins-5 hours: the satellite picks up the signal (depending on when the satellite next passes over the region you are in, and relays it through for evaluation, providing an approximate area of about 20km. That’s big.&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Aircraft that are in that area (private or commercial) are requested to provide a bearing on the signal. This may never happen, if there are no aircraft.&lt;/li&gt;&lt;br/&gt;&lt;li&gt;Depending on the situation, a helicopter crew is requested to deploy to the area to locate, and air-lift or support a ground recovery.&lt;/li&gt;&lt;/ul&gt;&lt;br/&gt;So, the upshot is you could be waiting a long, long time for a response. The major problem is that 97% of all analogue EPIRB’s are false alarms. Kids playing in their shed find one in the fishing boat – apparently they are inundated with alarms during school holidays.&lt;br/&gt;&lt;br/&gt;For this reason the analogue system is being shut down and replaced with a digital system.&lt;br/&gt;&lt;br/&gt;The digital system is different in that a personalised ID is sent with the signal – which allows emergency response to obtain details on the owner of the PLB. Also the signal is received within 3 minutes, without the delays caused by satellite overpass. Contact with the owner via mobile phone is attempted, and background details consulted to work out what the likely scenario could be. From here the process is very similar to that of analogue, except that the location is a little more specific – but still an enormous area to search.&lt;br/&gt;&lt;br/&gt;The practical solution is a digital PLB with GPS. With this device the GPS location is transmitted, meaning that the response team have an exact location within 3 minutes. This allows them to further validate the incident, since the location gives a good guide, and respond quickly with appropriate response (possibly land not air).&lt;br/&gt;&lt;br/&gt;So, the moral of the story is – don’t rely on an analogue EPIRB to give you a 10-30 minute response time (I was told 1 hour would be the very best case). My use for a PLB is mountain biking in mountainous terrain, and an anonymous signal in a 20K region is not all that useful. Digital with GPS is the way to go, when they get released later in the year (~$600).&lt;br/&gt;&lt;br/&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114766453706801867?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114766453706801867/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114766453706801867' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114766453706801867'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114766453706801867'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/05/epirb-and-plbs-emergency-transmitters.html' title='EPIRB and PLB&apos;s: emergency transmitters'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114535667501782881</id><published>2006-04-18T20:37:00.000+10:00</published><updated>2006-10-12T21:10:49.801+10:00</updated><title type='text'>Answer to XML namespace question</title><content type='html'>&lt;a href="http://www.lovettsoftware.com/"&gt;&lt;span style="color:#000000;"&gt;Chris Lovett&lt;/span&gt;&lt;/a&gt;&lt;span style="color:#000000;"&gt; gave me an answer to the previous question (I promised I'd post the answer) on XML namespaces. Why does the framework create redundant xmlns='blah' attributes when parsing XML into the DOM.&lt;br /&gt;&lt;br /&gt;Chris filled me in:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;You are correct.  Default namespace attributes is redundant.  But there’s another wrinkle.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;The XPath spec requires that namespace:: axis return actual namespace attributes, so it’s handy to have them in the tree for this purpose also.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;color:#666666;"&gt;&lt;span&gt;XmlDocument doc = new XmlDocument();&lt;br /&gt;doc.Load(@"..\Employee.xml");&lt;br /&gt;foreach (XmlAttribute nsa in doc.DocumentElement.SelectNodes("namespace::*"))&lt;br /&gt;{&lt;br /&gt;  Console.WriteLine(nsa.Name + "=" + nsa.Value);&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114535667501782881?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114535667501782881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114535667501782881' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114535667501782881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114535667501782881'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/04/answer-to-xml-namespace-question.html' title='Answer to XML namespace question'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114535648858596321</id><published>2006-04-18T20:34:00.000+10:00</published><updated>2006-10-12T21:10:49.740+10:00</updated><title type='text'>ASP.NET Challenges</title><content type='html'>I've been doing a bit of ASP.NET lately, which is a first for me really since the original ASP days. Short of the more-than-impressive Microsoft demos I've really only had superficial exposure to it. I have seen so much about the impressive productivity benefits of data-binding and the like – time to find out.&lt;br /&gt;&lt;br /&gt;Why am I doing ASP.NET? It's not really my thing to create data-driven websites, but I have a new product in the real estate industry that requires such a platform. (hoping to launch it in the next week)&lt;br /&gt;&lt;br /&gt;Lets just say the whole data-binding thing is impressive, but when you use it in anger you get.. well.. angry. I had this "Ground Hog Day" experience of looking up problems I was encountering on Google – only to find everyone else with the same questions, and very few answers. The big ones I'll summarise here.&lt;br /&gt;&lt;br /&gt;The first one is where you bind something to an ObjectDataSource, which is then connected to a TableAdapter – and you want to do updates on a table that has a key. You will inevitably find your way to the error:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;&lt;span style="font-family:Verdana;font-size:130%;"&gt;ObjectDataSource 'MyDataSource' could not find a non-generic method 'Update' that has parameters: [data columns], original_[key field]&lt;/span&gt;&lt;/em&gt;&lt;span style="font-family:Verdana;font-size:130%;"&gt;.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Verdana;font-size:130%;"&gt;&lt;/span&gt;&lt;br /&gt;Essentially the problem is that read-only fields are never supplied as parameters. Note this error only happens when the key field's ReadOnly is true in the control you are bound to. If you set it to false the field is supplied and everything works fine.&lt;br /&gt;&lt;br /&gt;Maybe it is correct, but it sure is ugly annoying. There should be an easier way to produce an Update call on the TableAdapter that does not include the setting of the key values.&lt;br /&gt;&lt;br /&gt;And that is exactly the solution – create a custom UpdateX() on your TableAdapter (in the XSD designer) to take the exact list of fields that you are updating. Then bind to that UpdateX() call in the ObjectDataSource. Makes sense, since sometimes you don’t have all the data for a row, so you need a SQL statement to just target them.&lt;br /&gt;&lt;br /&gt;As far as improving ASP.NET 2.0 – I'd like to see the ability for DetailsView and similar to bind to a ObjectDataSource via DataTable's not just parameter lists. Then you can edit only the bits you care about (who cares then about which ones you aren't), and you don’t need to create custom update queries.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114535648858596321?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114535648858596321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114535648858596321' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114535648858596321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114535648858596321'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/04/aspnet-challenges.html' title='ASP.NET Challenges'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114410519342642801</id><published>2006-04-04T08:59:00.000+10:00</published><updated>2006-10-12T21:10:49.682+10:00</updated><title type='text'>WPF: Auto-expanding TreeView</title><content type='html'>How do you auto-expand items in a WPF TreeView? &lt;a href="http://www.beacosta.com/2005/09/how-can-i-get-listboxitem-from-data.html"&gt;Beatriz Costa&lt;/a&gt; (Microsoft) gave me this tip. Basically, create a style for the TreeViewItem's:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#999999;"&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&amp;lt;Style x:Key="AlwaysExpand" TargetType="{x:Type TreeViewItem}"&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;    &amp;lt;Setter Property="IsExpanded" Value="true"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&amp;lt;/Style&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;.. and then use it on the TreeView:&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#999999;"&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&amp;lt;TreeView ItemsSource="{Binding Source={StaticResource doc}}"&lt;/span&gt;&lt;br /&gt;&lt;strong&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;             ItemContainerStyle="{StaticResource AlwaysExpand}"&lt;/span&gt;&lt;/strong&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;             Margin="0,0,0,0"/&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Much easier than responding to change events, and manually expanding each TreeViewItem as it is created. Done!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114410519342642801?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114410519342642801/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114410519342642801' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114410519342642801'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114410519342642801'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/04/wpf-auto-expanding-treeview.html' title='WPF: Auto-expanding TreeView'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114402498735384857</id><published>2006-04-03T10:42:00.000+10:00</published><updated>2006-10-12T21:10:49.625+10:00</updated><title type='text'>XML namespaces</title><content type='html'>A few tricks I found with XML text/DOM mismatches.&lt;br /&gt;&lt;br /&gt;When you read some XML text with a namespace (eg. &amp;lt;root xmlns="testns"&amp;gt;), this actually sets the .NamespaceURI to "testns" on the element (as expected), but also creates an attribute called "xmlns" with a value of "testns".&lt;br /&gt;&lt;br /&gt;I found that .NET 2.0's implementation will ignore the .NamespaceURI value if you change the attribute. This begs the question: why read it as an attribute at all. If you create the element natively in the DOM (specifying the namespace at creation), it does not rely on such an attribute being there, so why include it..&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114402498735384857?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114402498735384857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114402498735384857' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114402498735384857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114402498735384857'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/04/xml-namespaces.html' title='XML namespaces'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114378015113403880</id><published>2006-03-31T15:42:00.000+11:00</published><updated>2006-10-12T21:10:49.271+10:00</updated><title type='text'>XML bits and pieces</title><content type='html'>&lt;span style="font-family:Georgia;"&gt;I have been doing some QA work on MotionSet (part of &lt;/span&gt;&lt;a href="http://www.vertigotechnology.com/superset.aspx"&gt;SuperSet&lt;/a&gt;&lt;span style="font-family:Georgia;"&gt;). A few things have jumped out at me, particularly when reconciling the three manifestations of XML data:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Georgia;"&gt;XML text (ie. angled brackets)&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Georgia;"&gt;XML DOM object model&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Georgia;"&gt;XML Information Set&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:Georgia;"&gt;The first is text nodes. The DOM handles adjacent text nodes fine - but when they get rendered to XML text, the distinction is lost between that and a single text node. I cannot see any way to preserve the DOM in this instance, when transporting via XML text (an email to a XML guru at MS pending..).&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Georgia;"&gt;This opened up some other issues with the Infoset, where I discovered the DOM is quite distinct from the Infoset. In one case, I added and removed some child nodes from an element (this is in a DOM). Prior, it rendered as "&amp;lt;root/&amp;gt;" but after it rendered as "&amp;lt;root&amp;gt;&amp;lt;/root&amp;gt;". I thought the DOM would act more Infoset-like in this case and collapse it back to "&amp;lt;root/&amp;gt;". See the end of this post for a solution. (under the Infoset, these two representations are the same, since it models the underlying data)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Georgia;"&gt;So far I had been planning to target the Infoset, since it makes more sense long-term, just like targeting XHTML. They're not quite "here, now" - but they will take over things soon enough; and are close enough to XML text and HTML for people to understand them.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Georgia;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Georgia;"&gt;So, you are left with three distinct partially overlapping XML models. Most models have shortcomings of things it cannot do:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-family:Georgia;"&gt;XML text: distinguish between adjacent text nodes&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Georgia;"&gt;DOM: anything?&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-family:Georgia;"&gt;Infoset: distinguish between short and long form empty elements&lt;/span&gt;&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-family:Georgia;"&gt;It looks as if DOM is the most universal (trying to find some things it cannot do). Though, for mine, it is pretty close to Infoset as long as you don't care about the subtle difference between "&amp;lt;root&amp;gt;&amp;lt;/root&amp;gt;" and "&amp;lt;root/&amp;gt;".&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Georgia;"&gt;So, the only real problem facing us here is now to handle adjacent text nodes. Strangely the XML text format looks a bit inadequate when considering this. The only workaround I can see to use XML text to represent the following XML document:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#999999;"&gt;&amp;lt;root xmlns="someother"&amp;gt;&lt;br /&gt;This is the first text nodeThis is the second text node&lt;br /&gt;&amp;lt;/root&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;.. would be wrapping in a XML-based wrapper:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;color:#999999;"&gt;&amp;lt;x:document xmlns:x="somedodgytechnology.com"&amp;gt;&lt;br /&gt;&amp;lt;root xmlns="someother"&amp;gt;&lt;br /&gt;This is the first text node&lt;br /&gt;&amp;lt;x:delimiter/&amp;gt;&lt;br /&gt;This is the second text node&lt;br /&gt;&amp;lt;/root&amp;gt;&lt;br /&gt;&amp;lt;/x:message&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;.. a bit messy.&lt;br /&gt;&lt;br /&gt;As promised, the solution to the problem in .NET's XmlDocument where creating and deleting children to an element split it out into a start and end element tag is as follows. Basically it attaches to the event where nodes are deleted, and does a check on the parent to see if it is now empty. IMO the .NET implementation should do this - can't see any reason not to?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;doc.NodeRemoved += new XmlNodeChangedEventHandler(XmlNodeRemovedEvent);&lt;br /&gt;&lt;br /&gt;private void XmlNodeRemovedEvent(Object src, XmlNodeChangedEventArgs args)&lt;br /&gt;{&lt;br /&gt;  // does parent element now have no children?&lt;br /&gt;  if (args.OldParent != null &amp;&amp;amp;&lt;br /&gt;    args.OldParent.NodeType == XmlNodeType.Element &amp;&amp;amp;&lt;br /&gt;    !args.OldParent.HasChildNodes)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;    // make sure it gets market as empty&lt;br /&gt;    (args.OldParent as XmlElement).IsEmpty = true;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114378015113403880?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114378015113403880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114378015113403880' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114378015113403880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114378015113403880'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/03/xml-bits-and-pieces.html' title='XML bits and pieces'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114351289721417976</id><published>2006-03-28T12:37:00.001+11:00</published><updated>2006-10-12T21:10:49.147+10:00</updated><title type='text'>Post MIX</title><content type='html'>I happily brought home a cold on Friday from MIX06, which took me out for the weekend - and then gave my wife bronchitus. Now the whole family is not going so well :) Oh well, at least I had some pseudoephedrine to bring be down slowly from the highs of Vegas.&lt;br /&gt;&lt;br /&gt;Looks like local Australian David Richards started a fire late last week with his article &lt;a href="http://www.smarthouse.com.au/Computing/Platforms?Article=/Computing/Platforms/R7G5G6U4"&gt;60% of Windows Vista Code To Be Rewritten&lt;/a&gt;. My first reaction was exactly the same as yours I'm sure: only 60%? What about the other 40%?&lt;br /&gt;&lt;br /&gt;David likes a good juicy story, and must have followed up with &lt;a href="http://www.smarthouse.com.au/Computing/Software?Article=/Computing/Software/S8Q8K2Q6"&gt;this one&lt;/a&gt; to make sure the fire took hold. I hadn't talked to David in a year or so, so I checked his email address I had was still valid - he called me back.&lt;br /&gt;&lt;br /&gt;There has been a lot written on the now infamous "&lt;a href="http://www.windowsitpro.com/Article/ArticleID/47865/47865.html"&gt;It's not going to work&lt;/a&gt;" where it was discussed why the current approach to Longhorn needed to be "reset". The "reset" is known as the decision to abandon the approach of creating a completely new Windows built on the new .NET CLR technology. Instead, they decided to keep the status quo and ship the .NET CLR with the OS, but not actually use it - except some of the games maybe. That might be a bit harsh, but you get the drift: it's not like the core API will be managed .NET like it was originally envisaged.&lt;br /&gt;&lt;br /&gt;The parallells between the reset and the current angle by David Richards is very strong. It looks from the outside like David Richards is describing an alternate outcome, where MS decided to NOT to "reset". Pursuing this approach is the thing Allchin was talking about when he said "it's not going to work" - and that sounds like what someone looking down a canyon of a 60% rewrite would say.&lt;br /&gt;&lt;br /&gt;So if history is telling us that this all happened years ago, why is David Richards talking about this as if it is very recent? Well, as &lt;a href="http://www.windowsitpro.com/authors/authorid/879/879.html"&gt;Paul Thorrott&lt;/a&gt; said in his article Microsoft do railroad people when they are onto something true, when the PR machine want it not to be. This can have very bad consequences from Microsoft, when something is genuinely not true. I guess that is the key isn't it - we dont like to believe those who try to control the truth. The other key is that a liar wont believe anyone else (U2) - I just had to throw that one in.&lt;br /&gt;&lt;br /&gt;60% rewrite? Man I cannot imagine that given a wholesale ship in November. Maybe David Richards has other thoughts on the actual ship date though. Time will tell.&lt;br /&gt;&lt;br /&gt;Many at Microsoft are pretty pissed about this article: &lt;a href="http://blog.retrosight.com/PermaLink,guid,3316d2ce-815a-4db7-ad6e-f2980790acc7.aspx"&gt;Owen&lt;/a&gt; and &lt;a href="http://scobleizer.wordpress.com/2006/03/24/where-the-heck-is-scoble/"&gt;Scoble&lt;/a&gt; just to name two. All I can say is they will look pretty stupid if they turn out to be wrong, then again I thought that of all those WMD's as well.&lt;br /&gt;&lt;br /&gt;The progress of Vista "seems" to be fairly predictable now - the stabalisation, internal (Microsoft) rollout etc. Everything seems to be tracking as did 2000 and XP. In an alternative universe where Bills said "no reset" I can see David's picture coming true (a true disaster scenario). However, Vista seems to be pretty tame.&lt;br /&gt;&lt;br /&gt;What I have more difficultly with, is seeing how Microsoft will deliver on Bill's promise (at MIX06) to deliver smaller incremental updates to Windows. I mean, Windows has some serious design problems that will require a large scale rewrite, and many breakages to fix. The lack of security in the Windows messaging infrastructure for starters. I mean you really cannot trust anything you see on a Windows desktop - since it can be manipualted by any other application. Great for desktop utility writers, terrible for InfoCard. I need to read up on security in WPF to see if there is a bridge there someone to provide a legacy (insecure) sandbox for GDI apps. I have seen no mention of desktop security in WPF. Perhaps WPF hasn't been built that far out, fine, but I hope it has been at least thought of.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114351289721417976?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114351289721417976/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114351289721417976' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114351289721417976'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114351289721417976'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/03/post-mix_28.html' title='Post MIX'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114316955805553431</id><published>2006-03-24T13:55:00.000+11:00</published><updated>2006-10-12T21:10:49.023+10:00</updated><title type='text'>MIX Summary</title><content type='html'>&lt;p&gt;&lt;u&gt;MIXisms&lt;br /&gt;&lt;/u&gt;&lt;br /&gt;Here are some really cool terms (they are now soo last week) that got more than a few laps at MIX06. You could spin together a compelling discussion at MIX06 with only the following words available:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Mix It Up&lt;/li&gt;&lt;li&gt;Mashup / Mash It&lt;/li&gt;&lt;li&gt;Right click experience&lt;/li&gt;&lt;li&gt;User experience&lt;/li&gt;&lt;li&gt;AJAXness&lt;/li&gt;&lt;li&gt;Single click experience (usually said in a demo just after clicking at least 5 times)&lt;/li&gt;&lt;li&gt;[wildcard] experience (used to describe anything that would have previously been obvious)&lt;/li&gt;&lt;li&gt;GeoRSS&lt;/li&gt;&lt;li&gt;Microformat&lt;/li&gt;&lt;li&gt;Social Networking Site&lt;/li&gt;&lt;li&gt;RSSable&lt;/li&gt;&lt;li&gt;Affiliate program&lt;/li&gt;&lt;li&gt;How will you monetize that?&lt;/li&gt;&lt;li&gt;REST / SOAP / WDSL / AJAX or blah blahblahblah blahblah…&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;u&gt;IN SUMMARY - MICROSOFT&lt;br /&gt;&lt;/u&gt;&lt;br /&gt;Microsoft is a company people like to talk and bitch about. Being the biggest and best (financially at the least) means you do get your mix of opinions. Microsoft is like an economy of its own, with lots of companies (divisions/products/teams) within it. Each is competing (in part) with the others, for status (some say more so) and capital; each has its own story, its own view of the world, and its own plan for getting there.&lt;br /&gt;&lt;br /&gt;Microsoft is a company of contradictions. The big one is the fact that it likes to ask:&lt;br /&gt;&lt;br /&gt;Question: "Which companies here are developing their core business applications in .NET and taking advantage of the benefits of the Microsoft .NET platform?"&lt;br /&gt;&lt;br /&gt;The answer: not Microsoft.&lt;br /&gt;&lt;br /&gt;Microsoft's three main products (Windows, Office, IE) are native Win32. Their big pitch for a revolutionary new technology has so far fallen on deaf ears internally, with reluctance to use the new technology for its core revenue. This has at least two major effects: ISV's are frustrated that they become the bad guy who says customers need to install this .NET thing, and well - the MSDN Magazine guys must be pissed. All those wonderful glossy colored diagrams, gone to waste on the cold face of staunch opposition.&lt;br /&gt;&lt;br /&gt;Of course we need to balance that with the other attitude that people have towards Microsoft: the company which forces massive software updates down customers throats. Also, to be fair, Vista will fix this - now we just need to wait for everyone to buy a new PC. (I might go buy some Dell shares..)&lt;br /&gt;&lt;br /&gt;&lt;u&gt;ONTOLOGY OF MS&lt;br /&gt;&lt;/u&gt;&lt;br /&gt;Here's my theory: the Microsoft empire stack goes something like this: good-evil-good.&lt;br /&gt;&lt;br /&gt;Good: the guys at the bottom are like any brilliant, enthusiastic, professional bunch of software professionals you could ever meet. They are passionate about what they do, and want to deliver the coolest solutions to problems. They are not working at Microsoft to take over the world, rake in infinite amounts of cash, or harm anyone along the way. Most would be just as happy working on some open source project, or at Google or Yahoo - but they like Microsoft the most simply because they can achieve more there. They have the world’s eyeballs. Saying they would be happy working at Apple, I think would be taking it too far.&lt;br /&gt;&lt;br /&gt;Evil: maybe a bit of a harsh word, but this is to represent the business practices from the top are clearly very every-man-for-himself. The current new nice, glossy, warm fuzzy-bear-hugging show-me-the-standards personality is there because it is now in Microsoft's best interests to do so. Their position in the market is now best served with this strategy. It is not because they have concluded that their previous attitudes were at all "wong".&lt;br /&gt;&lt;br /&gt;Good: at the end of the day Bill is not making money to buy a bigger boat, or boost his ego. He is genuinely focused on improving the living conditions of those less fortunate as efficiently and effectively as he possibly can with the resources made available to him by his wealth. Bill makes sure that the entire company is actively involved in fund raising, and takes the responsibility for administration of such funds just as seriously as shipping software. Even if a few rich American tech companies get trampled along the way.. I mean they wouldn't give it away.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;SUMMARY - MIX06&lt;br /&gt;&lt;/u&gt;&lt;br /&gt;MIX06 was a great conference. I can still see the image in my head of the "designing for 10 foot" session with the glowing Apple logo from the laptop giving the presentation, elegantly perched on the intimidating (and clearly uncomfortable) Microsoft table. I did notice that many attendees did increasingly come out of the closet as the conference went on, by getting their Mac's out for increasing periods. By the end of the last day I think some people had gone and bought Mac’s to hang out and be cool.&lt;br /&gt;&lt;br /&gt;The IE team were *fantastic* - friendly, engaging and dying to find something that broke their browser (in a productive kind of way). Fortunately I was able to help them out with that!&lt;br /&gt;&lt;br /&gt;Bill was Bill, and plenty was reported in the press on it so there is no point rehashing. But he was a good sport to come down and put himself out for the press's analytical pleasure.&lt;br /&gt;&lt;br /&gt;MIX06 embodies MS's confidence with their position in the industry, letting their guard down, but that’s no risk to their complete dominance.&lt;br /&gt;&lt;br /&gt;On the constructive criticism side of things:&lt;br /&gt;&lt;br /&gt;- Speakers were often teleported away (often to Seattle) straight after their talks, and were not really that accessible. They were around, but there was never enough time to answer the questions from the usual suspects pestering them after the sessions with nerdy insights.&lt;br /&gt;- Developer-designer interaction was not really there, not sure how you would do it: mash-off? I would have loved to find some designer willing to help make by ugly pieces of functionality look slick in WPF..&lt;br /&gt;- WPF was not well represented, I came with a bunch of WPF issues that I hoped to work through face-to-face - but was left with a forum post.&lt;br /&gt;- Dean's "SEVEN" shirt on Ebay was not there as advertised. It was going to be washed first, right?&lt;br /&gt;&lt;br /&gt;ONLY IN VEGAS...&lt;br /&gt;&lt;br /&gt;I overheard someone overhear in vegas:&lt;br /&gt;1: "you're married?"&lt;br /&gt;2: "yeah."&lt;br /&gt;1: "for real?"&lt;br /&gt;2: "yeah, we have a dog and everything." &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114316955805553431?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114316955805553431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114316955805553431' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114316955805553431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114316955805553431'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/03/mix-summary.html' title='MIX Summary'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114304913160990990</id><published>2006-03-23T03:50:00.000+11:00</published><updated>2006-10-12T21:10:48.958+10:00</updated><title type='text'>MIX06 - Day Three</title><content type='html'>&lt;u&gt;INFOCARD&lt;/u&gt;&lt;br /&gt;&lt;u&gt;&lt;/u&gt;&lt;br /&gt;Phishing is a &lt;a href="http://www.antiphishing.org/"&gt;huge problem&lt;/a&gt;, is on the rise, and is causing individuals to reduce the amount of online purchasing. The number of known sites is in the order of 7,000 - with the number of sites almost doubling in December. Presumably at least partially due to seasonal factors.&lt;br /&gt;&lt;br /&gt;A very different beast from Passport. Basically it works by users creating their own self-issued Infocard, that contains all personal details you may want to exchange with others. At least then you are assured that identity is preserved - in that one user that comes back again later, is the same user. It does not assure that the identity is correct. Each card contains a list of "claims" - that is details; name, address, phone etc. All fields are optional, but may be required by any particular website in order to conduct business.&lt;br /&gt;&lt;br /&gt;You can then get the Infocard signed by third parties (professional associations, banks, government etc.) - there is no centralised "Passport.com"-style Microsoft master database. Though I'm sure Microsoft will participates&lt;br /&gt;&lt;br /&gt;Users have a list of cards, representing all the different cards you have in your wallet. All your department store, food and book store loyalty cards. Your ATM, Visa, health care cards etc. Then you can choose, in a way, which identity you want to show to a particular business. It is not about making a "master identity" in the same way that Passport did.&lt;br /&gt;&lt;br /&gt;A lot of UI security around freezing the desktop while a user manages/uses their cards. Presumably this to ensure that phishing sites don't try to mislead or confuse users.&lt;br /&gt;&lt;br /&gt;Self issued: ones you make up yourself, basically a encapsulated Google autofill, if you like.&lt;br /&gt;Managed Card: cards issued by third parties, where they endorse the claims in an Infocard.&lt;br /&gt;&lt;br /&gt;Makes extensive use of WS-*, so the comms will get pretty chunky - but it is pretty open. Infocard can interoperate with other systems (yet to be implemented, but MS say there is nothing proprietary in the interfaces..)&lt;br /&gt;&lt;br /&gt;There is a substiantial amount of the system that has a Linux-based open source implementation, and apparently the user UI is being implemented as well. All indications are from the standards focused (not just MS) that this will be interoperable. I think it needs to be, not another Passport.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;MICROSOFT RESEARCH&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;This was a pretty cool demo from a company who use MS's IP and use it to analyze raw traffic data.&lt;br /&gt;They take everything:&lt;br /&gt;&lt;br /&gt;- Traffic counters&lt;br /&gt;- Taxi cab locations&lt;br /&gt;- Traffic cameras&lt;br /&gt;- Toll booths&lt;br /&gt;etc.&lt;br /&gt;&lt;br /&gt;.. and they produce:&lt;br /&gt;&lt;br /&gt;- Current traffic conditions on every road segment&lt;br /&gt;- Current travel times for a given route&lt;br /&gt;- Predictive traffic conditions in the future&lt;br /&gt;- Predictive travel times for a given route in the future&lt;br /&gt;- An analysis of the departure time v length of journey, for a given route&lt;br /&gt;&lt;br /&gt;WAY cool. It deals with all pattern lengths - daily, weekly, monthly, yearly etc. Believe it used a basiean filter.&lt;br /&gt;&lt;br /&gt;VIRTUAL EARTH / MAPPOINT&lt;br /&gt;&lt;br /&gt;This was pretty good - if I were interested in mapping parts of America. I guess it would be useful if I lived there. Apparently our (Australian) government is not that interested in taking photographs of the place. Sounds like they haven't been able to get suitable snaps and maps of the colony. Lets hope they can get this data real soon so we can start working out convoluted solutions to pizza finding in arbitrary locations.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114304913160990990?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114304913160990990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114304913160990990' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114304913160990990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114304913160990990'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/03/mix06-day-three.html' title='MIX06 - Day Three'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114298647966920960</id><published>2006-03-22T10:18:00.000+11:00</published><updated>2006-10-12T21:10:48.890+10:00</updated><title type='text'>MIX06 - Day Two</title><content type='html'>&lt;u&gt;AJAX&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;A repeat of the usual AJAX hacks, issues and contradictions. I'm not a real fan, and have talked to quite a few people about the shortcomings. I need a working model to demonstrate some ideas - who knows what it will end up looking like.&lt;br /&gt;&lt;br /&gt;&lt;u&gt;Media Center&lt;br /&gt;&lt;/u&gt;&lt;br /&gt;There were 6 million units sold in the past year - more than I had thought. Four options exist for writing MCE apps:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;HTML: web pages loads within MC, the only option for MCE 2005. Can be used by any webbrowser as well. Ho hum.&lt;/li&gt;&lt;li&gt;WinFX: requires Vista (Home Premium or Ultimate), and is effectively a XBAP (XAML Browser Application Program) within MCE. This creates a seperate app, that is not integrated into MCE other than just being launched. Can be used on any IE/WinFX capable client.&lt;/li&gt;&lt;li&gt;MCML: locally installed Media Center Markup Language application allows you to add functionality to MCE, and is the same technology used for the the default functionality in MC.&lt;/li&gt;&lt;li&gt;MCML Web: this is markup generated dynamically by a webserver (IIS or other), but of course is targeted only to MC.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The Vista MC looks better in terms of functionality, but navigation I think is less intuitive (I must be missing something). The big push was towards the media extender (specialised boxes plus xbox) - so the model is, leave your PC in your office - and have an xbox in the living room. Not a bad model.&lt;/p&gt;&lt;p&gt;MC is obviously going more mainstream than Steve Jobs, or I, had invisaged. As an owner of a MCE 2005, it is not quite "there" for my parents. There must be lots of me out there.&lt;/p&gt;&lt;p&gt;A great session on 10' design - that is how to design an application for use on a large screen, where you are about 10 feet away. I am not a designer, so it was more than a bit depressing (even the bad examples are far better than anything I could produce :)&lt;/p&gt;&lt;p&gt;&lt;u&gt;myspace&lt;/u&gt;&lt;/p&gt;&lt;p&gt;The myspace.com guys were nice enough to invite us all to a party at V Bar. A good night. These guys are on top of their world.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114298647966920960?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114298647966920960/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114298647966920960' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114298647966920960'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114298647966920960'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/03/mix06-day-two.html' title='MIX06 - Day Two'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114288965869464564</id><published>2006-03-21T08:13:00.000+11:00</published><updated>2006-10-12T21:10:48.830+10:00</updated><title type='text'>MIX06 - Day One</title><content type='html'>Day one started pretty well, here are the highy biased highlights:&lt;br /&gt;&lt;br /&gt;&lt;u&gt;FIRST SESSION&lt;/u&gt;&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;BillG&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Standard format presentation for Bill, with the usual trimmings of information describing what is going on at MS. Press were pretty scathing about something.. not enough Hollywood I think. And definitely not the next governor or president.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;MySpace&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;These guys are growing VERY quickly - like 200K+ new users PER DAY. Man. Had a demo of some new cool stuff which I can't remember any more - so it must not have been too compelling for me, but I am probably too old for their demographic. Featured the only heckler (Macromedia founder &lt;a href="http://blog.broadbandmechanics.com/2006/03/bill-and-tim-rap-it-out-i-ask-the-1st-question"&gt;Marc Canter&lt;/a&gt;), which I thought was going to be about the war, or censorship or something, but turned out to be something far more important: "open up your API". No comeback line was forthcoming.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;BillG -O'Reilly Face Off&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;This was pretty brave of Bill, but he got off pretty lightly. Not a guy you really want to tick off, but it was very good of him to expose himself to something that could have turned out to be far worse. Well done.&lt;br /&gt;&lt;br /&gt;One good one was O'Reilly gave him a bit of stick about all the knock-out blows delivered to competitors in the past (eg. Netscape - there are string of them...) by Microsoft. Bill's response was pretty cool - "there were a lot of supposed beat-ups where the other guy just knocked themselves out". Must be a lot of extremely bad swingers out there. There are enough of the "faithful" here to ensure this one will go down OK for Bill.&lt;br /&gt;&lt;br /&gt;Comments did cut a little deeper to imply that Microsoft "cut off the oxygen" to players that worked on the Windows platform after they had built a substantial business. The implication being that the reason for the web's success is due, in part, to the fear of ISV's in building huge businesses on Windows. Yahoo, eBay, Flickr, del.icio.us etc. When I thought about it, the life expectancy of a large ISV's building on Windows is not that great. Adobe is the next one on the block if history is to repeat itself. Interestingly Bill did not take the usual line that "Adobe are high end, some of our stuff touches there on the consumer end, but we're not really competitors". Instead he said they would coexist happily as competitors. When Bill says he is going to happily coexist with you - be careful.&lt;br /&gt;&lt;br /&gt;O'Reilly finished with a public invitation for Bill to attend a less friendly audience: his Web 2.0 conference later in '06. Bill responded with a typical polite and diffusing comment that got him off the hook without responding. I got the impression he wont be there.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;IE7&lt;/strong&gt;: "we screwed up", "we're listening now"&lt;br /&gt;&lt;br /&gt;Kick off with a self inflicted beat up on MS's decisions in relation to IE. While they didn't say exactly what those things were - most knew that MS had pretty much shutdown the IE team/development when they got to 95+% market share. So there was no IE team for (guessing here) 4 years or more. The IE team is back (well and truly), look for 9-12 month cycles next time. And innovation galore, none of this "we won the war - lets just sit back and milk it". They have done a great job, and the smart ones (Yahoo) are leaving them to dominate.&lt;br /&gt;&lt;br /&gt;Where do I get a "SEVEN" t-shirt? (with an IE "E" logo)&lt;br /&gt;&lt;br /&gt;Improvements:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Many (many) more layers of warnings (including roll-back) when users wind back security settings to get applications to work. Good luck to those call centers who rely on&lt;br /&gt;opening up IE to get Java/ActiveX based products to work. Might have to review those practises, or.. they can just find out the hard way.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;In discussions with the MS techs they did say specifically that ActiveX *was* being supported going forward. I talked a bit about all the bugs I had run into over the years with screwy Downloaded Program Files directory contents, and they looked a little blank. (not a known issue) Tough one to repro/track down, but my ActiveX days are over :)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Cool new interface, way simpler&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Security: major new features, including a long (longer) list of warnings when downloading ActiveX, green/red cue to tell you of dodgy websites (phishing blacklist, certificate mismatches, suspicious techniques etc.), or certified high-assurance sites (certificates are not available yet, but will be difficult to get).&lt;a href="https://)"&gt;&lt;br /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;RSS: the real story is the RSS platform; infrastructure that IE can front-end (very basic), but Outlook and Express will do the same thing as well. Not the death of readers, since&lt;br /&gt;they too will be able to plug-in to this common infrastructure. This is the new, warm, fuzzy and "give me a hug"-ing Microsoft. (that someone forgot to tell Bill about in his presentation). Sounds like they love everyone now, not just developers. The wierd bit is that it is native, with a COM interface - a .NET wrapper in the future. Go figure.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;RSS enhancements: new tagging functionality (ebay using it) to allow the new RSS platform to do more advanced filtering, sorting etc.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Some very clever new IE7 tools for developers/designers - basically to debug ActiveX controls, layout (CSS) issues etc. A nice HTML DOM viewer, that does Spy++-esque finding of nodes in the DOM&lt;br /&gt;&lt;/li&gt;&lt;li&gt;CSS improvements: lots better standards compliance. When you have 90%+ of the market, you want things to be open.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Open Search: this is quite good, an open standard (A7) for search/research providers so everyone can connect with the built-in IE7 search bar. Even unknown sites can easily advertise their search interface for users to subscribe. Also looks like a nice way to edge-out the Google toolbar, since the search bit is the major part.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;Atlas&lt;/strong&gt;: "this demo is for you"&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Gutsy demo with no prefab or prebake&lt;/li&gt;&lt;li&gt;AJAX cross-platform platform thingy blah blah, things I didn't know was:&lt;/li&gt;&lt;li&gt;Major part is a client-side library, so it works with PHP, Apache not just ASP.NET. Usual story... best with IIS but works with the rats and mice.&lt;/li&gt;&lt;li&gt;Supports Safari, not just IE and Firefox. &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;strong&gt;WPF&lt;/strong&gt; (Windows Presentation Foundation)&lt;/p&gt;&lt;p&gt;Not that much new really, a video replay of North Face Kiosk demo (cool - but didnt get any of the American "whooping" factor I expected)&lt;/p&gt;&lt;p&gt;Have only found some (little) expertise on WPF here so far, hopefully there are more out there. The branis must still be running hot up north.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Infocard&lt;/strong&gt;&lt;/p&gt;&lt;p&gt;The jetlag was starting to kick in around here...&lt;/p&gt;&lt;p&gt;An easy to use identity/certificate management system- containing personal details for users, so no more typing all the usual stuff you need to go through whenever you hookup to any website today. Looks good. I presume this is IE only, can't see how it could work with the others.&lt;/p&gt;&lt;p&gt;&lt;u&gt;AJAX: Show me the money&lt;/u&gt;&lt;/p&gt;&lt;p&gt;A bit of a recursive discussion on the state of AJAX, with a lot of non-specific generalisations on things. Real smart panel of people giving sometimes opposing views on things, which was great. My feeling was this whole AJAX thing is still very early, and poorly understood. I mean what is web 1.0, 2.0 anyway - the definitions seems to be very fluid.&lt;/p&gt;&lt;p&gt;&lt;u&gt;Future of Internet Explorer&lt;/u&gt;&lt;/p&gt;&lt;p&gt;A bit of a beat-up on the MS guys. I mean it is not their fault that the IE team was abanded to the wilderness for half a decade, so it seemed more than a little unfair on them. Don't shoot the messenger kind of thing. Anyway, MS well and truly communicated that they are on the standards bandwagon - the biggest (and unanswered) question from Dean was "do you want compatability or compliance". Unfortunately the panel were not thought-up on this issue prior, and seemed to find a way through to turn it into a bitch about the crimes of the recent past.&lt;/p&gt;&lt;p&gt;For mine, I think the ideal is to have backward compatability with some sort of identifier (a-la quirks mode), but then strict compliance going forward. If I have to choose, I would say compliance - better to break it now before the web grows another order of magnitude. In any case, leave HTML in the wilderness - and do XHTML strictly and properly. That might help to kick it along as well!&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114288965869464564?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114288965869464564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114288965869464564' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114288965869464564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114288965869464564'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/03/mix06-day-one.html' title='MIX06 - Day One'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114281554666039535</id><published>2006-03-20T11:33:00.000+11:00</published><updated>2006-10-12T21:10:48.774+10:00</updated><title type='text'>Sweet Sunday in Vegas...</title><content type='html'>Woke up late this morning (still adjusting), and went down to &lt;a href="http://www.shadowhills.org/"&gt;Shadow Hills Baptist&lt;/a&gt; who were genuinely suprised to see someone venture down from &lt;a href="http://en.wikipedia.org/wiki/The_strip"&gt;the strip&lt;/a&gt;. Pretty big operation down there - 1,000 people or so. Tom &amp; Debbie took me out for a tour, lunch etc. and answered a few questions that only locals can answer. Tried to buy some touristy toys for this kids, but this whole town (and everything in it) is labelled "not suitable for under 3 years".&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/5275/1960/1600/Picture%20009.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/5275/1960/320/Picture%20009.jpg" border="0" /&gt;&lt;/a&gt;Took a walk down &lt;a href="http://en.wikipedia.org/wiki/The_strip"&gt;the strip&lt;/a&gt; (I really hadn't seen it much yet), there is some crazy stuff there like this massive TV screen with an oval shield the size of a football field. (it actually moves up and down to block the light on the screen, below)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/5275/1960/1600/Picture%20001.jpg"&gt;&lt;img style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/5275/1960/320/Picture%20001.jpg" border="0" /&gt;&lt;/a&gt;The casionos are bigger than you can imagine, on acres and acres of land. Building is going on over the place&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/5275/1960/1600/Picture%20009.jpg"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114281554666039535?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114281554666039535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114281554666039535' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114281554666039535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114281554666039535'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/03/sweet-sunday-in-vegas.html' title='Sweet Sunday in Vegas...'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114273900746932525</id><published>2006-03-19T10:06:00.000+11:00</published><updated>2006-10-12T21:10:48.719+10:00</updated><title type='text'>Tour day</title><content type='html'>&lt;a href="http://photos1.blogger.com/blogger/5275/1960/1600/Picture%20023.1.jpg"&gt;&lt;img style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/5275/1960/200/Picture%20023.1.jpg" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Got up at 3AM local time, left for tour at 5:30PM - it was a blast. Helicopter trip over &lt;a href="http://en.wikipedia.org/wiki/Hoover_dam"&gt;Hoover Dam&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Grand_Canyon"&gt;grand canyon&lt;/a&gt; etc. I was big (isn’t everything here?) – but I suppose you expect that.&lt;br /&gt;&lt;br /&gt;Next was the &lt;a href="http://en.wikipedia.org/wiki/Hum-Vee"&gt;Hum Vee &lt;/a&gt;tour of the  dam, desert areas etc. On the way (read: out in the middle of the desert)  we met some real friendly Americans and made a promise that I would email Oprah about getting Bono onto her show. Go figure. Don't  know how that happened, but "only in America" could you get into that conversation...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114273900746932525?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114273900746932525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114273900746932525' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114273900746932525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114273900746932525'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/03/tour-day.html' title='Tour day'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-19743873.post-114265270165002903</id><published>2006-03-18T14:21:00.000+11:00</published><updated>2006-10-12T21:10:48.660+10:00</updated><title type='text'>Viva Las Vegas (sorry..)</title><content type='html'>On Friday... I said goodbye to the kids (plus Julie!):&lt;br /&gt;&lt;p&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/5275/1960/320/Picture%20032.jpg" border="0" /&gt; (had to throw that photo in)&lt;br /&gt;&lt;br /&gt;Here’s where the house is up to:&lt;/p&gt;&lt;p&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/5275/1960/320/Picture%20010.jpg" border="0" /&gt;&lt;br /&gt;I left Sydney mid-afternoon on Fri, after a stressful near-miss of the fuel gage. Who’s to say it really was as bad as it said – I mean how can there be “0KM left” when we were still moving. Hmm…&lt;br /&gt;&lt;br /&gt;&lt;a href="http://photos1.blogger.com/blogger/5275/1960/1600/Picture%20037.jpg"&gt;&lt;img style="FLOAT: right; MARGIN: 0px 0px 10px 10px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/5275/1960/200/Picture%20037.jpg" border="0" /&gt;&lt;/a&gt;Flew into LAX, then onto LV and have setup camp in the &lt;a href="http://www.venetian.com/"&gt;Venetian&lt;/a&gt; hotel (a pity Julie isn’t here to enjoy), in the main strip right smack in the middle of LV. The hotel has 4,000 suites (currently building to double its size), the place is expanding like there is only a tomorrow of oil. Truly amazing – an indoor replica of Venice complete with genuine-ishlooking (better than you’d think) piazzas and Gondola rides on the 4th floor.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mix06.com/"&gt;MIX06&lt;/a&gt; starts on Monday – should be great.&lt;br /&gt;&lt;br /&gt;My first impressions are, well, predictable. All the usual stuff about the slot machines the second you get off the airplane (they are too heavy to fly), and the occasional &lt;a href="http://cityguide.aol.com/lasvegas/top_monster_trucks/"&gt;monster trucks&lt;/a&gt; you see on the streets (people actually drive them), and the cheap gas that runs them (for now).&lt;br /&gt;&lt;br /&gt;Met a whole lot of friendly Americans who have been at pains to ensure I understood that LV is life to excess (even for Americans). Best I can tell is that it is the weekend escape from (for?) conservative America.&lt;br /&gt;&lt;br /&gt;But boy is this place moving. 4,000+ people per week (taxi told me 6,000+) with a metro population of 1.6 million (the taxi told me 2.5). Maybe the biggest growth is in, well, how much they think they are growing? Catholics, Mormans, &lt;a href="http://en.wikipedia.org/wiki/Hoover_Dam"&gt;Hoover Dam&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Lake_Mead"&gt;Lake Mead&lt;/a&gt;. Who’s got time for blackjack...&lt;/p&gt;&lt;p&gt;On the work side of things, have put together the building blocks for a XAML/WPF based XML document visualiser. The problem stopping integration of the pieces is there are some bugs in WPF (TreeView?) that are preventing it form working. Hopefully talk to someone (maybe Bill) on Monday about it.&lt;/p&gt;&lt;p&gt;So, today (Fri 17-Mar-2006) has lasted 43 hours - ouch. Since I haven’t really slept for 32 hours, it is time to get some zzz’s, up early tomorrow for a &lt;a href="http://www.grandcanyontourcompany.com/helohum.htm"&gt;grand canyon tour&lt;/a&gt;. If I can work out the time when I wake...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/19743873-114265270165002903?l=filmackay.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://filmackay.blogspot.com/feeds/114265270165002903/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=19743873&amp;postID=114265270165002903' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114265270165002903'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/19743873/posts/default/114265270165002903'/><link rel='alternate' type='text/html' href='http://filmackay.blogspot.com/2006/03/viva-las-vegas-sorry.html' title='Viva Las Vegas (sorry..)'/><author><name>Fil's Blog</name><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
