More on Zip in .NET

First, I’d like to thank everybody for their comments on the Zip APIs. It’s great to know that I’m working on something that a lot of people will hopefully find useful. I’ll try to address the themes that came up in the comments.

Apparently, there are a bunch of comments on how Zip should work in the BCL. I should read these and reflect on how to make NUnrar better.

Comments [0]

Studio Styles .info

I just stumbled upon a color settings sharing site for Visual Studio:  http://studiostyles.info/

I've submitted mine.  Mainly for backup purposes: http://studiostyles.info/schemes/secondary-colors

Filed under  //

Comments [0]

Read the fine print: DispatcherTimer

A DispatcherTimer will keep an object alive whenever the object's methods are bound to the timer.

After staring at Windbg attached to Silverlight and wondering how I can debug DependencyProperty reference chains, I looked at DispatcherTimer. Then I finally found this gem on the MSDN page.

Thanks.

Comments [0]

SQL CE 4 announced.

The biggest improvement is that it now designed and tested to work in a multi-threaded environment.  Previous releases of SQL CE only worked in client-apps and would corrupt/crash in server environments.  SQL CE 4 specifically supports server scenarios.

We also now support shared hosting and medium trust - which wasn't supported before.  We are also updating SQL CE's SQL support to be more compatible with SQL Server and enable easy optional migration.

Hope this helps,

Scott

The announcement of "New Embedded Database Support with ASP.NET" is enough to make me yawn. What is great is that it is actually SQL CE 4 and has the major improvement of allowing multi-threaded access.

Believe me, it is a pain to ensure single-threaded access in a multi-threaded app with needed continuous access to an embedded database. Especially when you didn't realize that random corruptions happen with multi-threaded access.

Filed under  //

Comments [0]

Amazing Discovery: Duplex Services

I found a new post about the Silverlight 4 improvements in Duplex Services the other day.  After reading up on Duplex Services a bit: http://msdn.microsoft.com/en-us/library/cc645026(VS.95).aspx and noticing a lot of the timeout issues my project was having I asked a co-worker: "have you seen this Duplex Services thingy?" and he said "oh yeah, I know about that."  I groaned and asked why weren't we using it and he just shrugged.

Since we were already Async WCF heavy, using Duplex Services was easy to switch to.  Now all of our long running processing problems were over.  Seriously.  Duplex Services keeps a channel open to have callback events to the client.  It basically just polls over and over again.  The SL4 improvements (https://blogs.msdn.com/b/silverlightws/archive/2010/06/25/http-duplex-improvements-silverlight-4.aspx) make it performant: http://tomasz.janczuk.org/2010/03/comparison-of-http-polling-duplex-and.html  I do recommend digging in the generated code to manage the DuplexChannel yourself.  The generated code is so nasty. 

Just to verify what was going on, I booted up fiddler2 to see what it showed.  I created made a service just run longer than the timeout then have an event callback.  I could see stuff going on but it was all nonsense since WCF using the .NET Framing Protocol.  Some Microsoftie did write a basic inspector for fiddler2: http://blogs.msdn.com/b/silverlightws/archive/2010/05/10/fiddler-inspector-for-wcf-silverlight-polling-duplex-and-wcf-ria.aspx

The only downside is that you really can't use the Async pattern.  What I've ended up doing is making pairs of one-way calls.  One for the server that the client calls, then the client one that the server uses for the callback.  You've basically have the client call the method then an event is fired on the client when the process is done.  You have to have an instance of a client object that maintains the callback for each call.  I'd rather use the Async pattern and pass state that way.  I guess you can't have everything.

Filed under  //

Comments [0]

Adventures in Silverlight 4 DataGrids

As the initial product cycle on the project I'm currently working spirals toward the end, the bugs I get often seem easy to fix but really are not.  This project relies very heavily on the Silverlight DataGrid and RichTextBox (which is new in SL4 and a bit incomplete, a joy for me to code around those holes).

This DataGrid problem manifests itself weirdly:  The user loads data into the datagrid, once the rows have been lazily populated from the server, the rows adjust size and now pressing the down arrow doesn't do anything until after a certain amount of presses have happened.

What happened is that the DataGrid calculated that certain rows were visible, say the first 25.  After the rows have been populated with data, they almost always grow in size to display more information.  Therefore, the visible rows should shrink.  In fact, the DataGrid doesn't know the viewable row count has shrunk because it doesn't know to recalculate the viewable area.

The data is lazily gathered because I implemented a basic Data Virtualization strategy for the DataGrid since the row count can be very small or very large and people do not want to wait any long period of time to "see" everything.  Paging just wasn't an option (already fought and lost that battle).

The solution is to simply reset the ItemsSource on the DataGrid (first set it to null then back to the collection) which will reset the DisplayData on the DataGrid then use ScrollIntoView to recalculate.

That all seems obvious now but it wasn't when I didn't realize it was only the initial load that was the problem and that I really just wanted to call ScrollIntoView again.  By the way, simply calling ScrollIntoView again didn't work because the DataGrid already thought that the row was viewable.  It wasn't because the previous rows pushed it out of view but the DataGrid DisplayData didn't get updated.

UI bugs always take the longest.

Filed under  //

Comments [0]

Sharing Silverlight Assemblies with .NET Apps - CLR Team Blog

For SL 4 and .NET 4, we have made the following assemblies portable:

  • Mscorlib
  • System
  • System.Core
  • System.ComponentModel.Composition
  • Microsoft.VisualBasic

I've only just now come across this information. I was hoping there would be more much more in common between Silverlight 4 and .NET 4 than just those assemblies (i.e. WCF parts and some UI). The common code could be put in new assemblies....oh well. I guess we can't have everything.

Comments [0]

This is wrong : Why enumerator structs are a really bad idea

If you've ever poked around the .NET class libraries in Reflector, you probably would have noticed that the generic collection classes all have implementations of their IEnumerator as a struct rather than a class. As you will see, this design decision has some rather unfortunate side effects...

The "side-effects" that are talked about here are the natural effects of dealing with a value-type. The same behavior would happen if he was wrapping an Int32.

The 99% use-case of a generic enumerator is in a foreach block. It absolutely makes sense to have an enumerator be a struct to cover this case and see real benefit.

All this is is a case of having to do a little be of research to correctly use a feature a little bit outside of it's intended use-case. We all use enumerators outside of foreach blocks but I'm willing to bet that foreach or LINQ statements cover 99% of whatever real coding you do.

Comments [0]

Adventures in Silverlight 4: Richtextboxes and DataGrids

I've had to discover the wonders of the RichTextBox in Silverlight 4.  Here's the worst thing about it: it's practically all native code.  The stacktraces mean nothing as they usually soon disappear into a native call.  So breaking execution or looking at Reflector does not help much.

The RichTextBox control is also not quite there.  While I'm very thankful for how it handles many MANY languages.  I've ran into a few problems that are major bugs.  The biggest, by far, is one that only happens in very specific yet not uncommon cases.

The bug must be some infinite loop in native code (since I can't see anything happen when I break execution) since CPU maxes out when it happens.  To get this to happen, I have to do the following: put the RTB in a DataGrid to display text in the rows, make the RTB be in RightToLeft, use InlineUIContainers, then start sizing the browser window.  Certain cases cause the CPU to just spin in the MeasureOverride method with these conditions.

Another problem, specifically with the DataGrid itself, is that it's Rows don't auto-shrink.  There are tons of posts about it:

http://forums.silverlight.net/forums/p/160830/375007.aspx

http://forums.silverlight.net/forums/t/71184.aspx

http://forums.silverlight.net/forums/p/133177/299525.aspx

http://forums.silverlight.net/forums/p/123169/277437.aspx

The only reliable fixes for me, so far are:

A) Forcing a resizing of RowHeight programmatically:

datagrid1.RowHeight = 10;
            Dispatcher.BeginInvoke(delegate
            {
                datagrid1.RowHeight = double.NaN;
            });

B) Changing the CellStyle of the DataGrid to have the Template's root Grid have a Top VerticalAlignment.

Even if I report the RTB problem, it won't be fixed until SL5 or be ignored/unsolved just like the DataGrid row sizing.

 

Update:

Using the B strategy (which is the best because A uses way too many resources) you also need to listen to the SizeChanged event of the control in the row that should govern the size.  In my case, it is the RichTextBox.  On SizeChanged, you need to get the DataGridCellsPresenter and set the height of the Presenter to the ActualHeight of the control.  Like so:

 

 RichTextBox control = sender as RichTextBox;

 DataGridCell cell = control.Parent as DataGridCell;

 DataGridCellsPresenter presenter = cell.Parent as DataGridCellsPresenter;

 presenter.Height = control.ActualHeight;

 

Filed under  //

Comments [2]

Careful with those enumerables

Careful with those enumerables

Ever since .Net 2.0 introduced the yield keyword for creating enumerators, and even more after the introduction of LINQ in C# 3.0, I've seen more and more APIs return IEnumerable<T> instead of IList<T> or ICollection<T> or their older cousins the ArrayList and the array object.

That makes sense most of the time, especially for collections that aren't meant to be modified, and choosing between those different return types is not what I'm about to discuss here. You can find endless articles and threads about that.

I'm a big sinner when it comes to IEnumerable. Need to remember that lazy evaluation can lead to unexpected side-effects.

Filed under  //

Comments [0]