October 2005 - Posts

Async Pages API
19 October 05 09:48 AM | despos | 8 comment(s)

Chapter 5 of Programming Microsoft ASP.NET 2.0 Applications--Advanced Topics is tentatively titled "Building Richer Pages" and discusses three topics that can deserve a (short) chapter themselves--async pages, custom $-expressions, and page parser filters. These are apparently unrelated but used together offer you an unprecedented power as far as the runtime behavior of the page is concerned. You can make the page work async, expand your macros at parse time, build your own list of safe controls (like SharePoint does).

 

When I started on async pages, guess what, the first thing I did was looking into the excellent Jeff's article on MSDN Magazine and a number of posts from Fritz. It went pretty good and smooth until I tackled the RegisterAsyncTask method on the Page class.

 

In brief, to build an async page you have two steps to accomplish:

 

  1. Add Async=true to your @Page directive
  2. Register the async task(s) to execute

#2 can be done in either of two (nonexclusive) ways: using AddOnPreRenderCompleteAsync or RegisterAsyncTask. Both are new methods on the Page class. The former adds a pair of Begin/End async event handlers to the PreRenderComplete event. The latter requires you to pack the same pair of handlers (and more actually) in a wrapper class--PageAsyncTask--to be passed as an argument to RegisterAsyncTask. The tasks execute in between PreRender and PreRenderComplete on distinct threads--typically, the Begin thread is an ASP.NET worker thread and the End thread comes from completion thread pool.  

 

Functionally speaking you get pages working exactly in the same way. Is there any difference? And why two distinct APIs? Here are some thoughts and findings:

  

  • RegisterAsyncTask is a kind of independent API for executing tasks async from within an ASP.NET page. Unlike AddOnPreRenderCompleteAsync, it doesn't strictly require Async=true, though
  • RegisterAsyncTask works also with Async=false (at least in Beta 2). The original thread that started the Begin phase is blocked until all operations are complete. If you use tracepoints (coolest feature ever of VS2005 that I found out about only yesterday) you see that the thread of Page_Load is the same of Page_Unload.
  • For obvious scalability reasons, you might typically want to use RegisterAsyncTask in conjunction with async=true. However, the API is somewhat independent from async pages
  • AddOnPreRenderCompleteAsync targets a multicast delegate so you can repeatedly call it to register multiple tasks. All these tasks execute sequentially to guarantee that the page renders only when all tasks are complete. Using tracepoints you see Begin/End Begin/End Begin/End sequences for each registered task. The thread on End triggers the next Begin. There’s no attempt of getting some parallelism
  • If you want to obtain parallel execution with AddOnPreRenderCompleteAsync you must write your own IAsyncResult—which is boring but not hard (also thanks to a couple of posts from Dmitri). You use one Begin/End pair and fire internally all required async tasks.  
  • For one single async task, using RegisterAsyncTask (with Async=true) or AddOnPreRenderCompleteAsync is the same
  • For multiple simultaneous tasks, you either use multiple calls to RegisterAsyncTask (with Async=true) or one call to AddOnPreRenderCompleteAsync with a custom IAsyncResult object to track the termination of all tasks.
  • Using RegisterAsyncTask (with Async=true) makes your life considerably easier and results in simpler code to write

 

Using RegisterAsyncTask has also some other plusses:

  

  • The End thread enjoys a richer context. It has impersonation info, intrinsics, HTTP context. For example, if you registered the task using AddOnPreRenderCompleteAsync, you can't rely on integrated security to access a database in the End handler. Likewise, you can't use HttpContext.Current to trace or access intrinsics
  • Timeout support. You can define a timeout handler which runs if any of the tasks is not complete after a number of seconds (45 by default)
  • Possibility of parallel execution (parallel execution is not the default, though)
  • Much simpler (and I’d say cleaner) programming model for multiple tasks
  • You can use the ExecuteRegisteredAsyncTasks method (on Page) to start tasks on demand. For example, in a postback without waiting for the unwind point between PreRender and PreRenderComplete

The bottom line?

 

  • Use AddOnPreRenderCompleteAsync for one task, opt for RegisterAsyncTask for multiple tasks   

 PS: I'm aware that a lot of details about async pages are missing here (i.e., what the heck the unwind point is?). For an overview (and more) read the Jeff's article on MSDN Magazine.

 

DevConnections sessions I'd really love to be able to attend...
18 October 05 09:10 AM | despos | with no comments

DevConnections is just around the corner--I just submitted yesterday the final deck of slides for my control development workshop. As my travel plans come to a final stage, I started looking into sessions being held there that are of greatest interest to me now. Here's a list.

Applying Object-Oriented Principles and Design Patterns to Web Development. I find out that I've been using patterns for years without realizing that. However, more often than not I find out that I still need a little bit more of formalization to come up with patterned and replicable solutions working and well architected. Markus promises to bring a full bag of goodies for this talk.

Caching Features in ASP.NET 2.0 with SQL Server 2005. Obviously, the possibility of using SQL Server changes to invalidate cached data is great. I still need to see described and applied this in real-world and realistic scenarios. I tried it a couple of times and found out that there are quite a few caveats. It's not that trivial in most cases. Steve, show me the way...  

Why You Need to Use a Code-Generator in ASP.NET. To save time, I suppose. And time is money. Code generators seem to be a quick and effective way to come up with good code with little effort. But if there's more, I'm here to learn. BTW, in ASP.NET 2.0 with code-generators and build providers might be quite a powerful duo...

Asynchronous Pages in ASP.NET 2.0. I'm surprised how elegant is this feature in its core implementation. (PS: I spent a week trying to reverse engineer most of steps it takes a request to be fully processed async-ly.) And I might have quite a few questions for Dmitri--one of the MS brains behind it.

Migrating from Web Services to SOAs. This is not exactly my core business at this time. I have a lot to learn.

Synchronous and Asynchronous Web Services in .NET 2.0. The interest for this is related to the previous two talks.

Unit Testing and Build Management in .NET Applications. Along with design patterns, unit testing is another aspect of development that is hot for me these days. And thanks to msbuild I'm finally seeing most of old dreams coming true.

Performance Tuning and Monitoring your ASP.NET Applications. A classic session for most conferences. As Don Box said to me once, two people can say the same things, but the perspective of each remains unique. You might conclude that such a session is poor for you; but it is always important to take a closer look. Moreover, in ASP.NET 2.0 the health monitoring is quite interesting...

More information and abstracts and speaker info here.

This said, I'm quite sure I won't be able to attend most of them because of simultaneous talks of mine or other business. :(

Authoring controls
18 October 05 08:53 AM | despos | 4 comment(s)

As you all know controls are an essential part of ASP.NET pages. Building controls is an as much essential part of the skillset of most developers. Authoring controls is quite easier in ASP.NET 2.0 due to a number of intermediate classes that incorporate most of the techniques and practices that you had to code manually in previous versions. I'm sharing some thoughts and code on the ASP.NET DevCenter.

The first installment live is relatively simple as it deals with deriving controls from existing ones. I describe how to build a DropDownList with an additional API to set the colors of the displayed items--but it shows events, custom properties and a bit more. Future articles will cover trickier aspects of control development such as styling, rendering, themes, control state, viewstate, binding, templates.

A journey of thousand miles begins with a single step. That's mine. Enjoy!

My workshop at DevConnections
04 October 05 05:45 PM | despos | with no comments

In my previous post, I omitted details on the full-day ASP.NET workshop scheduled for Friday Nov 11.

A Crash-course on ASP.NET 2.0 Control Development
I usually envision a full-day seminar at DevConnections as a session divided in four modules of approximately 90 minutes each. Four modules like the four main types of custom controls we have in ASP.NET--new/derived controls, data-bound controls, composite/templated controls, controls with some "script" capabilities. Basically, I plan to spend each module to cover one of the above families of custom controls. I think I may announce with good approximation the code and the samples I'll be discussing. (Slides and code are due in a couple of weeks, so I have still time to change my mind ...) In the first module, I'll discuss derived controls, namely controls that are built from a significant existing class. For example, a DropDownList with additional capabilities. My sample will show a drop-down list with an additional API to color items. A very special type of derived controls are brand-new controls--controls built starting from WebControl that require custom logic for control state, styles, rendering, and so on. I'll probably show a headline control to render title, icon and description of a news.

The second module is about data-bound controls. I'll add data-binding capabilities to the Headline control so that text and description can come from a data source--be it a data source or an item of an enumerable collection. Next, I'll show how to use ASP.NET 2.0 base classes to create (quickly) a custom list control class--the HeadlineList control.

With the third module, things get more complex as we'll delve deep into composite controls. Composite controls build a tree of child controls and maintain a list of child items. Not sure what control I'll build here--it could be a 100% pure HTML bar-chart with header and footer templates.

Finally, if time allows I'll discuss how to add script capabilities to ASP.NET controls. I could create a DHTML-enabled version of the Headline control (click to expand the title and show the abstract) or perhaps build a script-callback enabled control. (This is something that I'll be showing in my script callback talk too, again if time allows)

I should also be able to sprinkle some design-time tips here and there to spice up the workshop.

I've used several times the phrase "if time allows...". Should time not allow for all planned demos, no worries. You'll still be able to get full source code in various ways, including:

Hope to see you in Las Vegas!

My sessions at DevConnections
04 October 05 11:28 AM | despos | 5 comment(s)

With the official DevConnections blog now open, I feel the need to share some thoughts about the sessions I'm down with.

ASP.NET Script Callbacks
First and foremost: this talk is NOT about Atlas :) I'll explain the mechanics of the ASP.NET raw API including some nitty-gritty details about viewstate and callbacks. Once the working of the core API is clear, you are in the mental condition of catching major shortcomings and ways to improve it. Here's where Ajax.NET fits in. With Atlas and the future evolution of ASP.NET controls (which I believe it's the real added value of Atlas) being covered in other talks, my session basically provides an annotated overview of what "script callback" means today. The Ajax.NET model is extremely easy to use and powerful. But it uses the same engine as the ASP.NET raw API. The difference is in the services surrounding the basic API--the perhaps old-fashioned XmlHttpRequest object. I like Ajax.NET; bad luck it doesn't provide (yet?) a truly cross-browser client DOM to mitigate the issues of client-side programming with code that works on IE but not on Firefox or vice versa. 99.99% of the time, the script callback API (whatever it is) has nothing to do with it. It's a matter of using the wrong DOM call... Back to the contents of the session, I'll write and comment pages to make script callbacks with ASP.NET 2.0 and Ajax.NET. I'll also briefly illustrate a custom control that like GridView and TreeView uses script callbacks to improve its user interface and behavior. Mine will be a validation control that uses script callbacks to perform server-side validation without postbacks. Full source code available.

Data-bound ASP.NET 2.0 Controls
Writing data-bound custom controls for ASP.NET 1.x was not a picnic. And it was mostly because of the lack of guidelines, best practices, codified patterns. In core-coder terminology, the lack of intermediate base classes to derive from. Thankfully, these classes (a lot of them, actually) exist in ASP.NET 2.0 and are smart enough to make it transparent for you the real data source object you're bound to--be it a data source control or a plain enumerable object. My session will discuss these new base classes and how to use them. A couple of examples--new list-controls--complete the talk along with some words on the internal overridable methods of the data binding engine. Full source code available.

Inside the ASP.NET Page Machinery
This last-minute talk (it was added to my schedule a few days ago) covers the page machinery, that is what happens in the ASP.NET runtime until the compiled-on-the-fly page is called. Almost all ASP.NET developers know what the Page class is and what purpose it is for. You all know that pages are compiled on the fly. But can you honestly say you can explain it to new hired consultants, significant others, friends in a step-by-step way? Sure, your significant others probably don't need to know about ProcessRequest and HTTP handlers unless they're involved with ASP.NET programming. Developers might need to know about it because ASP.NET 2.0 gives you an additional chance--interact with the parsing process that creates the dynamic page from the ASPX source. If you just author pages with VS facilities and you're happy with that, you need not come. All others should. It would be interesting to see how many people will make it ...

I'll also have a talk in the VS Connections track.

Async Commands in ADO.NET 2.0
Asynchronous commands in ADO.NET are not for Windows Forms applications--perhaps the first (only?) scenario you can envision for them. Async commands do not hold onto a separate thread and wait for it to terminate the potentially lengthy task. Why? Uhm, it's mostly because commands typically run from within a DAL, that is a server-side piece of code. In a context where scalability is a serious thing. Blocking a thread might be painful in such a scenario. For this reason, async commands are implemented through overlapped I/O and provide key advantages to middle and data tier code. To get results, you can use sync objects as well as callbacks. Why not in WinForms? Because WinForms are not thread-safe and will likely require UI updates when the operation has completed. You need to issue cross-thread calls to update the UI of WinForms when an async command terminates. Add this to the fact that in a client-side scenario like a WinForms app, blocking a thread is usually NOT an issue and you see the light. Async commands in WinForms are not prohibited or illegal; they're just unfit. You can use BackgroundWorker and get even better performance. Do not expect perf gains in WinForms out of async commands. Async commands are excellent for (certain) ASP.NET pages, as we'll see in the session.

 Hope to see you in Las Vegas!

More Posts