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]

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]

WPF : Showing you how to use PRISM in a very unlike PRISM way

I need to refresh myself on !PRISM! now that .NET 4 is actually here. Silverlight 4 is my primary environment now though.

Filed under  //

Comments [0]

I missed this: Microsoft Demos Silverlight on the iPhone

Filed under  //

Comments [0]

Building the Hello MEF dashboard in Silverlight 4 - Part I

The master of MEF, Glenn Block, shows off a simple usage of MEF in Silverlight 4. I hope the later parts show some more complex scenarios as I'm relatively unfamiliar with Silverlight specifics. So far, just client WPF experience for me. I hope to change that soon.

Filed under  //

Comments [0]

Microsoft enables Silverlight video streaming to iPhones

Filed under  //

Comments [0]

Lack of cross-platform support in Silverlight 4 explained

As with any new release, in Silverlight 4, Microsoft has made some changes that developers like and others do not. There are too many to list of the former, and just a handful of the latter, but one of them is quite serious: cross-platform support has become less of a priority

Does anyone really want COM-like support on Mac or Linux?

The HTML control is a problem. I think the only way to fix it is to have a HTML rendering engine built on the CLR. Actually, I wish they'd do this anyways. I really don't like using MSHTML in .NET

Filed under  //

Comments [0]

Silverlight 4 Trusted Applications: A better Clickonce?

The channel9 article for Silverlight 4 Moving-Beyond-the-Browser--Trusted-Applications shows what the new Trusted Applications with Elevated Permissions can do. It feels like it may be an even easier Clickonce scenario.

It can get COM objects and has full file system access. I guess the only catch is if you can write your entire application in Silverlight 4. It seems like more and more people probably can.

Filed under  //

Comments [0]

What's New in Silverlight 4

Read the technical whitepaper that walks through the new features in Silverlight 4 Beta.

Some of the stuff I was reading on Glenn Block's twitter sounds exciting. I'm afraid for myself that I'm excited about Silverlight 4

Filed under  //

Comments [0]