# Tuesday, September 23, 2003

I’ve been a big fan of XMLSpy for a long time.  It’s one the best XML tools out there, and I’d have to say the very best schema editor.  Now with their new version 2004, you can integrate XMLSpy directly into VS.NET, and use all the functionality of XMLSpy without having to leave everyone’s favorite development environment.  Very cool stuff. I much prefer the schema editor in XMLSpy to the database-centric one that ships with VS.NET, so it’s nice not to have to launch yet another app to get at it.  

Tuesday, September 23, 2003 1:43:08 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, September 15, 2003

I love appropriate applications of technology, and I just came across a really cool one.  Our public transit system here in Portland (Hillsboro) OR now has up to the minute bus tracking information available for cell phones (trimet.org/wap) and wirelessly connected PDAs (trimet.org/pda).  You put in what route and which stop you are at, and it will tell you when the next bus is coming.  How cool is that?!  As someone who both has a WAP phone and commutes to work on public transit (since I can’t afford one of the new 2004 Prius), I’m pretty excited.  This is possibly even better than WAP/PDA accessible movie times, which was formerly my favorite application of wireless technology.  Since they are pretty static, I actually get my movie times through AvantGo on my PocketPC (a ViewSonic v37).  

Monday, September 15, 2003 6:32:05 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 

If you haven’t already, check out the PDC episode of Red vs. Blue.  Talk about an appropriate use of technology… 

Monday, September 15, 2003 1:18:29 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, August 27, 2003

Werner Vogels posted a great article on what Web Services are and aren’t, and why they represent Service Oriented Architecture, and not a Distributed Object Architecture.  Don’t let the name SOAP fool you.

Wednesday, August 27, 2003 4:01:35 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 

Just finished struggling through yet another Windows Forms issue that had us completely baffled.  Writing multi-threaded WinForms applications brings up some very interesting challenges, and involves learning a bunch of new stuff, some of which is not at all obvious.  See my previous posts on InvokeRequired for a good example. There end up being some really interesting consequences of the boundary between the CLR only world, and the underlying implementation where windows have to deal with message pumps.  While WinForms insulates us from the real underlying PeekMessage calls, they are still there, and at some point the rubber has to meet the road, so to speak.  The problem I just had to deal with is way to complicated to even summarize here, but the core of the problem was that if I call Thread.Sleep on short intervals in a loop with calls to Application.DoEvents in between, the GUI doesn’t update correctly, but if I call Form.ShowDialog then it does.  WinForms knows something about message pumping that I don’t, which doesn’t really come as a surprise. 

Some days I think that this is way harder than MFC was, but on other days (like today) I realize that the real difference is that WinForms frees us to hurt ourselves in new and different ways that were too hard to achieve before.  I can only think that’s a step in the right direction. J

Wednesday, August 27, 2003 3:33:59 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 

It’s a bit off topic, and not strictly speaking technical, but I’ve got to say I’m totally digging Rhapsody.  For a very reasonable fee ($25 a quarter) I can now listen to something like 20,000+ albums from anywhere I’m online.  Much easier than trying to haul around 10 or 20 Gb worth of MP3s, and I can play music from anywhere there’s a broadband connection.  There’s no activation or other association with a given machine, so as long as I remember my credentials I can listen from anywhere (one place at a time, of course).  So if I really want to listen to Rob Zombie, Fatboy Slim and the Rolling Stones in the space of 20 minutes ( I hadn’t realized what a Rob Zombie fan I really am ) it’s all there.  There are a few noticeable holes in their collection, but they’re adding new albums all the time, so I have high hopes.  And best of all, it’s legal and guilt free.  And if I really must listen to something when I’m not online (which doesn’t seem to be all that often) then I can burn most of their tracks to CD for $.79, which is comparable to Apple of Buy.com’s offerings. 

Groovy

Now if only Rhapsody supported the blogging plug-in… (Right now it’s Mad Flava by Fatboy Slim)

Wednesday, August 27, 2003 3:10:18 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, August 13, 2003

Fixed.  If we move all our initialization code to run after the controls have been fully created and added to their parent’s Controls collection then everything works just fine, and InvokeRequired returns what it should.  Again, the more I think about this problem the more it makes sense that it would work this way.  However, what I would expect is for the call to InvokeRequired to throw an exception if it can’t really determine the right answer (e.g. isn’t initialized properly?) rather than just returning false.  If it had thrown an exception we would have found the problem right away, rather than having to discover it the hard way.  And since calling InvokeRequired on a control without a parent is apparently an exceptional case, it would be the right thing to do. 

If anyone who reads this is or knows a PM on the WinForms team, you might mention this issue. J 

Wednesday, August 13, 2003 2:35:03 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Monday, August 11, 2003

I spent some time late last work working with my colleague Jeff Berkowitz on what seemed like a pretty sticky problem.  He’s got some more info about the problem here, but the quick description is that we were in a situation where Control.InvokeRequired was apparently returning an incorrect value.  Our code was clearly running on a thread other than the GUI thread, and yet InvokeRequired returned false.  Disconcerting to say the least. 

Jeff spent quite a bit of time tracking down the problem over the weekend, and the conclusion that he came to is that if you want to call Control.InvokeRequired and get a rational and deterministic answer, the control you are calling it on must be embedded in the control containment hierarchy all the way up to a top level Form.  What we were doing involved creating controls but holding them in memory without putting them into the “visual” hierarchy of the application, meaning that they were not contained by a parent Control or Form.  Apparently if that is the case, InvokeRequired doesn’t return the correct results.  (Note that so far this is based on experiential evidence and not “scientific” data.)

The longer I think about this the more I’m not surprised that this is the case, but I’ve never seen any hint of documentation (from MS or otherwise) that indicates that this is true.  The solution (at least for us) is pretty straightforward, and involved moving some initialization code until after all the controls have been fully created and sited in forms.  Not a big deal, but it does prevent us from doing some up front initialization in a place where our users wouldn’t notice it.  Now it’ll take a progress dialog.  Seems like a reasonable price to pay, but it would, of course, be nicer if it worked the way we expected it to.

Monday, August 11, 2003 4:05:21 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Tuesday, August 05, 2003

So far I’ve done some experiments with a couple of the options I mentioned in my last post.   I tried styling the incoming XML document into something I could read into a dataset, and then used SqlDataAdapter.Update to persist the changes.  This works pretty well, but the biggest issue ends up being foreign key constraints.  I think you’d either have to do some pretty funky stuff in the stylesheet, or clean up the foreign keys once they were in the dataset, although that only works if your dataset doesn’t have constraints to begin with. 

Then I tried OPENXML, and I’ve got to say that so far that’s the way I’m leaning.  It turned out to make things much easier if I style the incoming XML into a simpler format (without all the namespaces) then pass that to OPENXML.  The OPENXML code turned out to be way less hairy than I had thought it might be, and I can handle the transaction in the stored proc rather than using DTC transactions.  All in all, not a bad thing.  It’s almost enough to make me not care if things change in Yukon in ways that would make this not work, or be obsolete.  It’s pretty slick in the near term.  I haven’t tried any performance testing, but it seems to me that the OPENXML solution is faster. 

I could try the other option of parsing the XML in C# and then making transacted ADO.NET calls to persist the data, but I don’t really want to go there.  It’s the business-layer XML parsing I’m trying to get rid of, and it’s a lot more code. 

Tuesday, August 05, 2003 7:34:08 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [0]  | 
# Wednesday, July 30, 2003

When new data comes in from monitors, it needs to be processed and then stored in the DB.  (See Xml on Large Power Transformers and Industrial Batteries for some background.)  I’m currently pondering how to manage that, and what I’m thinking is that I’ll process the incoming data as XML, using XPath and some strongly typed methods for doing inserts.  The issue I’m wrestling with is how to get the XML data into the database.  We’re currently using SQLXML for some things, so I could style it into an updategram.  Initially I was thinking of just chucking the whole incoming XML doc into a stored proc, and then using SQL Server 2K’s OPENXML method to read the document inside the stored procedure and do all the inserts from there.  The advantage is that I can rip up the doc and do a bunch of inserts into normalized tables and keep it all in the context of one transaction in the sproc.  Also, it keeps me from having to write C# code to parse out all the stuff that’s in the doc and do the inserts from there (although that’s also an option).  Usually I’m opposed to putting much code into the DB, since it’s the hardest bit to scale, but in this case it wouldn’t be business logic, just data parsing, which seems like a pretty reasonable thing for a database application to do. 

With that all out of the way, my concern is that OPENXML is fairly complex, and would require some relatively involved TSQL (which I can do, but would rather not, and hate to maintain).  Also, I worry about it all being made irrelevant by Yukon, which is supposed to have some pretty wizzy new XML related data storage stuff.  

Another option would be to style the incoming data into a dataset and use ADO.NET for the dirty work.  Since I’m really only ever doing inserts, not updates, it should be pretty straightforward. 

Sigh.  Too many choices.

Wednesday, July 30, 2003 7:27:59 PM (Pacific Daylight Time, UTC-07:00)  #    Disclaimer  |  Comments [2]  |