Josh Lane on .NET RSS 2.0
 Saturday, June 02, 2007

I've been poking around with the Silverlight 1.1 alpha release bits lately. My interest is probably a bit different than most folks... the whole RIA thing is certainly very interesting, but I'm exploring the idea of using .NET in the browser to enable background processing scenarios for web apps.

My company builds financial apps that do long-running, CPU-intensive calculations. These are typically rich client, Windows-based applications. Recently, we've begun exploring how to move some of our core processing functionality into web applications, and distribute it to a larger audience. Now, it's one thing to scale server software (even with CPU-intensive work) for a few users... it's another thing entirely to have hundreds of users hammering away on your server infrastructure.

I've explored some options for scaling our processing out, using dedicated server farms and well-known distributed processing architectures... there are caching and latency issues there, as well as deployment and configuration concerns. But those are solvable problems.

But once I saw Silverlight, I immediately started thinking beyond the fancy UIs and about how we can leverage that browser-based runtime for doing real background work. This allows us to offload work from the server, and localize it to its point of origin... so users who initiate lots of processing through their own actions are themselves paying the "CPU tax", and users who do little processing don't pay the price.  Woohoo server scalability!

Okay... so I started working on some simple Silverlight prototypes for doing background processing. System.Threading is there in almost its entirety... this is a Good Thing.  Very easy to spin up a thread, do some work, then synchronize back to the main UI thread. But now we've got a problem.

In Windows, you can't update your user interface from a background thread. Many windowing primitives (textboxes, etc.) use thread local storage to hold their state... so the thread the controls are created on (i.e. the main UI thread) is the only thread that has access to that state. This is a known problem that has existed in Windows programming for years. In .NET, we have a few mechanisms for dealing with it... BackgroundWorker is one, and the Control.InvokeRequired/Control.Invoke pattern is another. (As an aside, if you want to learn how to use these properly, you should sit in on DevelopMentor's Essential .NET class, which I happen to teach ;-) ).

So... back to the problem. I don't see BackgroundWorker or Control.Invoke/Required defined anywhere in the Silverlight version of the CLR! BackgroundWorker isn't really expected... it's fairly WinForms-specific. But no Control.Invoke and friends is a problem. So even though I can spin up a thread to do background processing in the browser, I can't update my UI as a result of that processing without resorting to hacks like this. Bah.

I know, I know... it's an alpha release. But System.Threading in Silverlight becomes significantly less useful without some easier means of accomplishing this. Anyone got any better ideas?

Saturday, June 02, 2007 2:48:16 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Silverlight

I've been busy at work for the last several weeks, and haven't had much time with the blog lately. But I noticed that the spammers found me, so I've had to disable comments for now. I hope I can turn them back on soon.

More to come on what I've been digging into... SharePoint 2007 and AJAX-ilicious web parts, Silverlight and DLR stuff (woohoo!), LINQ and C# 3.0 enhancements (double woohoo!).  Oh, and I'm gearing up to teach DevelopMentor's WF course in late July, as well!

Hope I get to go fishing sometime soon...  :-)

Saturday, June 02, 2007 2:15:16 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -

 Friday, March 23, 2007
Friday, March 23, 2007 10:14:16 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Programming
 Wednesday, March 14, 2007

Last weekend, Cary and I spent a few hours hiking the Benton MacKaye Trail in the north Georgia mountains, near Skeenah Gap.  We climbed Rhodes Mountain, to the point at which the BMT meets up with the Duncan Ridge Trail.  It was just under a 1000 foot elevation gain over a few miles, so nothing too strenuous (especially since we left the girls with Grandma this time ;-) ).

No pictures unfortunately, but nevertheless a great walk in the woods.

Wednesday, March 14, 2007 9:33:16 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Hiking
 Thursday, March 01, 2007

Saw this post today describing basic guidance for when to use the different numeric data types available in C#, apparently from someone on the C# compiler team.

It's amazing how many developers go through life lacking even a basic understanding of the appropriateness of one numeric data type vs. another, for a given situation. I've found this to be especially true for financial applications... if I had a dollar for every time I saw floating point datatypes used in database schemas or source code to represent employee salaries, or bank account balances, etc., I'd own a ski house in Park City, like I'm always dreaming about. :-)

For the sake of completeness... if you're modeling flocks of birds or something, go ahead and use floating point types. But please do our collective profession a favor and use fixed point data types (that's System.Decimal in .NET, or decimal/money/smallmoney in SQL Server) if you're doing calculations involving money, or in general when rounding errors are not tolerable in your problem domain (like, you know, with money and stuff :-) ).

One more thing... the last line of advice reads this way:

Byte, sbyte, short, ushort, uint, and ulong should only ever be used for interop with C code. Otherwise they're not worth the hassle.

I'm pretty sure I can't agree with this, in particular for unsigned types. The author explains that unsigned types can be confusing, if you're not expecting values to wrap around from the lowest possible value to the highest. For example:

 

// some C# code...
uint x = 5;
uint y = 6;
uint z = x - y; // hmmmm...

Debug.Assert( z == uint.MaxValue );	// evaluates to true...

 

It's true that this will surprise some people the first time they see it. And I suppose with the unsigned types you're more likely to encounter this issue than with the signed types, since values close to zero occur more naturally "in the wild" (I guess)... but the fact remains that the signed data types work this way, too...

 

// more C# code...
int x = int.MaxValue;
int y = 1;
int z = x + y;

Debug.Assert( z == int.MinValue ); // again, true...

So I'm not sure what avoiding the unsigned types buys you, from the standpoint of avoiding this potential confusion. At the end of the day, it's probably best to simply understand how this stuff works, and don't arbitrarily limit your use of some language or platform feature only because someone else tells you it might be confusing.

Thursday, March 01, 2007 9:53:16 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
C#
 Tuesday, January 23, 2007

I'm still mucking around with ASP.NET AJAX (get your 1.0 RTM bits here, y'all) and I needed a client-side "progressbar"-type thingie to display during AJAX postbacks. Note that I don't care much about "10% done... 20% done...", etc. I just wanted to give the user some visual indication that something's happening behind the scenes (especially since the entire page isn't visibly refreshing itself... this being the whole point of UpdatePanel and friends in the first place).

There are bazillions of Javascript progressbar implementations out there, but I wanted one that simply ping-pongs back and forth forever... that way you can show/hide it as needed in client-side code, to indicate background work of some sort.

I stumbled on Sahil Malik's implementation, which wasn't quite what I wanted, but close. He wrote a custom WebControl that allows you to specify percent complete and all that... so I modified it to do what I wanted instead.

For those who may not know, custom WebControls give you complete, well, control over their rendered output... so not only does the control emit the necessary HTML (just a table and a few columns, really) but it also emits the Javascript that does the animation. So the control is self-contained and pretty easy-to-use (IMHO).

Here's a demo, and here's the source. If you're using AJAX, try combining this with UpdatePanel, UpdateProgress and friends... pretty easy to achieve a decent user experience. Cheers.

Tuesday, January 23, 2007 5:55:16 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
ASP.NET | Javascript
 Thursday, January 18, 2007

Following are my notes from a WCF asynchrony demo I worked up a while back... thought it might interest somebody.

This WCF example works with the AdventureWorks demo database in SQL 2005. It illustrates mixing and matching synchronous and asynchronous processing in a WCF service and client. Specifically, the code shows:

- synchronous client code invoking synchronous service code ( not a big deal, admittedly :-) )
- synchronous client code invoking asynchronous service code
- asynchronous client code invoking synchronous service code
- asynchronous client code invoking asynchronous service code

 

Support for asynchrony is baked directly into the WCF contract (interface definition) using the AsyncPattern property of OperationContractAttribute. Such an interface also must adhere to the .NET asynchronous execution pattern (BeginXXX and EndXXX method pairs, use of IAsyncResult call object, support for callbacks, etc.). Here's the contract definition from the demo (edited down a bit for easy reading):

 

[ServiceContract]
public interface IAdventureWorksDataServiceAsync
{
	[OperationContract(AsyncPattern=true)]
	IAsyncResult BeginGetSalesPersonData(AsyncCallback cb, object state);

	SalesDataTable EndGetSalesPersonData(IAsyncResult result);
}

[ServiceContract]
public interface IAdventureWorksDataServiceSync
{
	[OperationContract]
	SalesDataTable GetSalesPersonData();
}
 

The important point here is that sync/async processing is a local implementation detail of clients and/or services. With WCF, the choice of synchronous/asynchronous processing on one end of the wire need not surface in the programming model on the other end. The demo client code can make calls against IAdventureWorksDataServiceSync, and the server can process such requests on an object that implements IAdventureWorksDataServiceAsync, or vice versa.

 

Think about that for a moment... it's pretty cool that the WCF infrastructure gives this to us for the cost of a few attributes. It's not unlike async page processing in ASP.NET, where the client just types in a URL and has no idea that special ThreadPool magic is happening on the server. 

 

A few additional points:

 

- Notice that, in the cases where you have sync <==> async processing (or vice versa), the client and server endpoint contracts don't reference the exact same physical interface definition; "matching" client and server contracts must be type-compatible, but not necessarily modeled on the exact same interface.

- The server-side benefits to async processing are primarily 2 fold: 1) separate the resources (threads, in this case) needed for accepting requests from the resources (threads) needed to process requests, and 2) spend as little time as possible accepting requests (as opposed to processing them, which "takes as long as it takes").

- The oft-repeated client-side benefit to async processing is the ability to not tie up a UI thread waiting for a remote request to return a response. The demo illustrates this.

- For a bit of insight into what happens inside ThreadPool, pay attention to the console output of Host.exe, and take a look at the async Start and End methods on the server side.

 

Enjoy!

Thursday, January 18, 2007 8:27:16 PM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
WCF
 Wednesday, January 17, 2007

Note to self... when using <location> tags in your web.config file, like so:

 

<location path="SomeFile.aspx">
	<system.web>
		<authorization>
			<allow users="*"/>
		</authorization>
	</system.web>
</location>

DO NOT use root-relative paths (AKA "tilde" paths) to specify the path attribute value... otherwise you spend several hours trying to figure out why your location-specific configuration overrides aren't being honored at runtime.

Or so I've heard. <sigh>

Wednesday, January 17, 2007 9:30:16 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
ASP.NET
 Sunday, January 14, 2007

Yesterday, Cary and I hiked the summit of Blood Mountain with Mallory, Darby, and Reggie. This is the highest point of the Appalachian Trail in Georgia, at 4458 feet. The weather was overcast, so the views weren't quite as good as on a bluebird day, but still worth the effort. We followed the east-to-west route from Neel's Gap up to the summit... it's about a 2.5 mile hike each way, with roughly a 1500 foot elevation gain. Fairly strenuous, and all the more so with a little girl strapped to your back!

Despite a few rough patches with the girls (they were getting pretty hungry as we neared the summit :-) ), it was a great trip. Here's a few pictures we took at the summit.

 

The whole gang, including Reggie

the whole gang on blood mountain  

Cary and the girls near the summit shelter, built in the 1930s by the CCC

blood mountain shelter

Mallory, Daddy, and Darby

blood mountain shelter2

Daddy "getting some exercise"

j and m on blood mountain

Darby expressing her dissatisfaction with riding vs. walking

c and d on blood mountain

Sunday, January 14, 2007 10:47:16 AM (Eastern Standard Time, UTC-05:00)  #    Comments [0] -
Hiking
Disclaimer

Don't blame my employer(s)... all of this is my fault.

© Copyright 2008 Josh Lane
Sign In
Locations of visitors to this page
DasBlog theme 'Business' created by Christoph De Baene (delarou)