Bomb Proof Http Cache Utility?

September 9, 2009 16:38 by Rob

I’d like to share this piece of code with you all.

Usually, when you use the System.Web.Cache classes, you do something like:

object x = Cache[blabla];
if(x == null) //not in cache
{
    x = …..;
   
    // add to cache
    Cache.Add(x, …);
}
// do something with x here.

Now this is not very thread-safe, because when 2 threads arrive at the ‘if’ at the same time, the object is constructed twice. The second one to complete will just overwrite the cached result of the first one (get it?).

So, in order to avoid this you can add a ‘lock’ statement around this to avoid filling the cache twice.

lock(typeof(ClassName))
{
   …

}

This will essentially avoid that 2 threads will enter the same code at the same time.

The problem with this approach is that there is a significant amount of code for every time that you want to read or write to the cache. The code is very error-prone but it is basically the same pattern over and over.

With generics and delegates you can develop a function that behaves like so:

object x = Cached.Get<object>(“cacheKey”, TimeSpan.FromSeconds(5),
                            () => new object()
                       );

The lambda expression ()=> new object is the fragment of code that is executed to populate the cache. The “cacheKey” is some sort of string that uniquely defines what information you want to retrieve. The key should in theory contain all the parameters for your population method.

Now there is a huge potential problem inside the Get() method. The lock statement (typeof(ClassName)) inside is essentially the same one over and over, so *all* calls through this method will be blocked and serialized, thus reducing concurrency to zero. If you have long-running or expensive population methods (you will, because that is why you are caching) you’ll be slowing the system to a halt.In effect, you’d want a separate lock for every 'cache key’ literal.

To overcome this problem, I developed an implementation that generates a new lock for every key. However, when reading and updating the HttpUtility Cache you should be very careful for race conditions.

CacheUtility.cs (7,11 kb)

This class provides strongly-typed access to the HttpCache. It also provides helper methods to flush a single or all elements that were cached using this method, and also a way to determine groups of cached elements. This way you can flush only a subsection of your cache.


Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: ASP.Net | C# | Software Engineering
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Quotes and more quotes

July 17, 2009 13:36 by Rob

I just saw this article with computer quotes, and I found it to be quite hilarious.

“The Internet?  We are not interested in it.”
– Bill Gates, 1993

“Pessimists, we’re told, look at a glass containing 50% air and 50% water and see it as half empty.  Optimists, in contrast, see it as half full.  Engineers, of course, understand the glass is twice as big as it needs to be.”
– Bob Lewis

“It was a joke, okay?  If we thought it would actually be used, we wouldn’t have written it!”
– Mark Andreesen, speaking of the HTML tag BLINK

“Perl: The only language that looks the same before and after RSA encryption.”
– Keith Bostic

“Yes, we have a dress code. You have to dress.”
– Scott McNealy, co-founder of Sun Microsystems

And finally, since I’m working with UXP professionals:

“We have to stop optimizing for programmers and start optimizing for users.”
– Jeff Atwood

 

 

For more great quotes, check here.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Large file upload using Silverlight, ASP.Net and WCF, Part 1

February 14, 2009 16:53 by Rob

In this article I would like to show you how I created a reusable ASP.Net component to handle large uploads using Silverlight 2.

The solution contains of 3 components:

  • A Silverlight control that allows the user to browse for files (this page)
  • A WCF service that receives the file data
  • An ASP.Net control that raises an event when the file has been uploaded.

I will discuss them one at a time. The code blocks are screenshots, but don’t worry because I attached the file below.

Edit: After posting this, somebody pointed out that Tim Heuer has a surprisingly similar screencast called Silverlight 2: OpenFileDialog and File Upload. The big difference is that Tim doesn’t support very large uploads.

The Silverlight Control

Using Visual Studio 2008, create a new Silverlight application,delete the standard Page, and add a control named ‘UploadControl’.

image

The control will look like this.

image

This control contains 2 buttons, a progress bar and a display message. The buttons are on top of each other and so are the progress bar and the message.

The magic of this control is in its code behind though. When the upload button is clicked i show a file selection dialog. After a file is selected, some housekeeping is done and a new instance of an UploadState class is initialized.

image

You will notice that 3 events are wired up:

  • One event is raised when the upload is completed
  • Another event is raised each time a block of data is transferred
  • And finally one event may be raised when the user has clicked the cancel button.

The rest of the event handling in this class is rather trivial. The UploadState class is where all the magic happens.

After creation and initialization of the UploadState instance I will start the upload:

image

This section of code needs some explanation, but before I do that, I need to tell you how to achieve large uploads.

Large Upload Intermezzo

IIS, Web services and pages don’t like large requests. Requests tend to time out and no progress can be shown. There have been lots and lots of solutions using ISAPI handlers, background processes and other weird solutions that all have their pros and cons.On Asp.Net forums there is actually a thread about large uploads which at time of writing consists of a massive 182 posts.

The approach presented here may not be unique, but I think it is a great alternative. The steps for large uploads in this solution are as follows:

  • The client requests an upload token from the server. I like Guid’s, to a Guid it is.
  • After the client has received the upload token (or handle as I call it), i can begin to send chunks of data to the server, 8kb at a time. Every chunk is a new http request so timeouts aren’t likely to occur.
  • The server will collect the chunks.The token is sent with the data chunk to the server knows what file the data belongs to.Since the chunks are numbered it can reassemble the entire file.
  • After the last chunk is sent, the client informs that all chunks have been sent.
  • The server receives the completion signal and will assemble all the chunks back into a single file.The server then sends an ‘All Ok’ back to the client.
  • The client has received word that the file has been stored on the server. The file can now be retrieved using all sorts of methods.

Back to Silverlight…

The Silverlight Control, continued

Here’s the ‘StartUpload’ method again.

image

Of course you know that all WCF communication in Silverlight must be asynchronous. This is what happens here. A WCF client is obtained, and a service call to ‘GetHandle’ is executed. The anonymous delegate is fired when a handle is obtained. After the block number and progress values are initialized, the first block is pushed.

Blocks are pushed using the PushBlock method. This method will read a chunk of data from the client’s file and send it asynchronously to the WCF service:

image

Problem with asynchronous calls is that it is impossible to use a standard while loop to enumerate all the blocks. But we can make another call to ‘PushBlock’ when this block is sent, using the anonymous method: (sender, e) => { PushBlock(); }

After every chunk is sent, the remote server is informed:

image

When the server has acknowledged the Complete method, the Completed event is raised from the UploadState class to the control in this method:

image

Again, more housekeeping. The final bit is at the end, where the FileID property is set and the FileUploaded event is raised. The FileUploaded event is a top-level event written for the client of the upload control. You can use this upload control in another Silverlight control, or you can expose it to the Html object model. In my project, i did it using the following code in  App.Xaml

image

The RegisterScriptableObject essentially exposes the UploadControl instance as an object named ‘uploadControl’ in JavaScript. We’ll come back to that later when I wrap the control into and ASP.Net component.

On the next part, I will dive into the implementation of the WCF service.

That’s it for now, keep tight. I need a break.

Rob.


Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Repository base classes with LINQ to SQL and performance.

July 18, 2008 19:14 by Rob

I read an article on CodeProject about implementing the repository pattern with Linq To SQL.

I tried that approach because it sounded very nice. I did have some problems with performance and after a few debugging sessions (showing the SQL trace or the DataContext log) I found the problem.


By defining the virtual methods of the repository base class like this: public IEnumerable<T> FindAll(Func<T, bool> exp) the Func will not be (what I call) a delayed method, but it will be expanded immediately. I checked the log from the DataContext and it shows that the table is no longer queries using a where clause. Instead, a full table load is performed and the function is evaluated in memory.


However, the solution is very easy, although this mean you'll have to include the Linq assemblies to your testing bed:

protected T Single(System.Linq.Expressions.Expression<Func<T, bool>> exp)
{
    return Items.Single(exp);
}


The trick is to wrap your functions in a System.Linq expression. Client usage is exactly the same. The performance gain on my project was huge, If you consider that tables are no longer loaded completely into memory.

The full code for my repository base class is in the link below.

Repository.cs (4,64 kb)


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Dynamic Data and Silverlight?

July 6, 2008 19:00 by Rob

Yesterday I saw a demo on the new Dynamic Data contribution to Asp.net 3.5. It literally blew me away (really) because that was what I've been doing for most of my time over the last couple of years.

The base

Basically, we develop custom data driven web sites with Asp.net. Most of the time this also involves some kind of back-end content management. What our mini-cms actually did was the following:

  • Inspect the database model
  • Enrich that model with metadata such as preferred input method, validation and comments and associations,
  • Generate a whole lot of Asp.Net controls from the aforementioned properties,
  • Inject a lot of role-based security-stuff,
  • Present those forms to the end-user to allow basic site management.

So, what we had to build was a configuration file with all the meta data, the database, and of course the web site that got driven by that data.

Not any more. I'm out of a job.

With Visual Studio 2008, Asp.Net 3.5 framework and Dynamic Data the generic application that we wrote can be thrown out of the window, because with the DataContext designer this is not longer something somebody else will pay us to do. As you can see in the demo, by binding your decorated data model to the starter solution, you have an interface in a matter of minutes.

Fortunately the Internet-facing site cannot be generated yet. And, we can embrace the DynamicData technology to our advantage and create sites even faster.

On to the subject of this post!

Silverlight and Dynamic Data

Now this is all nice, but there is a simple problem. If I wanted to use this technology with Silverlight, In the last couple of weeks, I was working on a Silverlight application for our content management concept, and I was wondering if the object model could be easily extracted with the new LINQ To SQL designer. I would have to transfer all meta data and content through a WCF service, right?

Lucky for me, the DynamicData layer isn't even finished and does not yet generate WCF services. So, in order to build a generic Silverlight application you would have to serialize a lot of unknown types into a Silverlight application that was unaware of those types. That is not really what I wanted. I wanted a pre-compiled application that can be configured with just a single configuration property: the data model.

I decided to give it a go, and here's what I came up with. I will try to explain it one step at a time.

Here's my very basic data model:

image

Just a news item for a particular category that can have zero or more attachments to it. Nothing fancy.

Using the designer, this stuff generates classes for me with the all the properties and data access methods (select, update, delete etc.) while maintaining all the relations.

Here comes the cool bit: Did you know that the DataContext class actually gives us all the meta data without having to use reflection?  Just drill down into DataContext.Mapping and see that you find there:

image

(edit: since GetTables is a method, it should be written as .GetTables())

Silverlight does not have this nice API, So I created my own WCF contract to serialize these properties in a separate class. Here's a sample of the type specification that I use to transfer to Silverlight (I left the part out that maps the MetaDataMember stuff to my own classes on purpose).

image

To serialize an item of a particular type I perform a generic LINQ select on the table, I read all the properties of a data item and put them in a dictionary so that Silverlight can read and display those items:

image

Notice that for this demo I used the Convert.ToString() method on the value to get a nice presentation of the value. In a future version I will need to put the basic values (int, string, DateTime etc.) in the Values collection.

Of course this is not finished by far. I needed a way to decorate the designed classes with validation, descriptions, etc. Because I do not yet have the DynamicData beta installed on my machine I decided to borrow their approach to decorate generated code. Here's a snippet for the NewsItem class:

image

Because the data context designer generates partial classes, we have the ability to add functionality to those classes. Since I only need to apply some attributes to the generated class I need to define the class again (as partial) and apply my attributes. Since I cannot redefine the properties of that class I have to create an extension class that shadows the properties of the generated class (very nice idea, DynamicData Team!). To use the attributes of the extension class I do need to use reflection, but that is only once. Here's a video of how it works and how it is used. I just copied the concept to there's little more to tell.

A lot of work still needs to be done but I hope you understand that the rest is just more along the same line.

Looks like I still have a job!


Currently rated 5.0 by 3 people

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tricks of the Trade - part 1

April 3, 2008 00:27 by Rob

I now have been working 12 years on software development and 8 years asp.net. I consider that to be a substational amount of experience. Because of this realisation, I'd like to share some things I've been learning of the years. I summarized my experiences, so check out this list:

  1. If you find the problem, look for the answer.
  2. If you find the answer, don't stop looking
  3. If you stop looking, experiment. 
  4. If you stop experimenting, make it work
  5. If it works, redesign
  6. If you're still not happy, you didn't understand the problem: back to square 1.

These are some mindblowingly simple steps. but they've always worked for me. They help, and not only in software! Number 1 and 2 are easy. That's (1) smart thinking and (2) google. We'll get to number 3 later on. The numbers 4 through 7 are simple development strategies you can read up on in tons of places.

I do like to elaborate on step 3. Most of my coworkers (and a lot of other people i meet) stop after #2. This usually happens after a couple of minutes or hours using google. By the way, if you know the problem, googling for an answer shouldn't last more than a couple of minutes. This is because google is very smart, but it doesn't know your problem. You're actually not googling for articles on the problem - you're googling for articles about the solution to that problem. This sounds strange because most articles talk about 'I have a problem with this and this', so the good google results should point you to an article or a thread that says 'I found the solution for this and this'. The trick here is to include words like 'solution' or 'best practice', 'I finally got it working' etc. to your search query.

Back to #3. Don't stop researching when you think you found the answer. To put it clearly: Number #3 is where the learning phase starts. Start working on a mind-map of the problem space. If you read enough articles on "How do I create custom controls?" for example, you usually cover a lot of the same subject matter, but if you deviate a little from the primary problem, you'll gain tons of slightly related knowledge. To illustrate, check out the class definition of a asp.net master page. I got there recently because I needed to know the base class of a MasterPage. That was easy to find - I also could've looked that up by pressing a help button in Visual Studio. I said 'for example' didn't I? Now as a case of routine I drilled down to the MasterPage Members, where I found out about two very nice properties named ContentPlaceHolders and ContentTemplates. I didn't know these existed, nor would I have found out about them in another way. Especially if you never think you'd need them. But I did need them. I had about a 100 lines of code in my application to find out what regions my MasterPage contains for a CMS i'm working on, but now I can simply refactor and clean up. The lesson I try to tell you is that browsing a couple of non-relevant links from you article *will* improve your knowledge. As you keep reading linked material you'll very soon connect some dots nobody else has ever thought about.


Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Why don't you use those expressions regularly?

January 21, 2008 15:45 by Rob
I found a very nice tutorial on Regular Expressions. If you're still a bit uncertain how it al works, or want to brush up on your RegEx skillz, check it out.

Currently rated 4.0 by 1 people

  • Currently 4/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5
Tags:
Categories: ASP.Net | C# | Software Engineering
Actions: E-mail | Permalink | Comments (0) | Comment RSSRSS comment feed

Put it to the test

January 17, 2008 11:58 by Rob

A very wise professor of mine once stated that testing (by definition) is not a way to find defects, but rather a way to determine the quality of the product.

When I read this post, I had an "Ah yes I know what you mean"-feeling. Testing-after-coding is usually regarded as a negative (or 'destructive role' as so nicely put). The reports from automated test suites such as NUnit usually give a success percentage, whilst the reports I usually receive is in most cases no more than a list of defects. Even better, the defects on these lists rarely relate to some or other feature stated in the requirements documentation. 

Granted, a product near completion will contain a lot of cosmetic bugs and annoyances that are not directly related to the requirements document. It is hardly possible to actually deliver a 100% bug-free product. But please focus on the quality please! If the product does what needs to be done, but crashes when you press Shift+Ctrl+Alt+F7+LMouseClick on the 2nd pixel from above, is that considered a critical defect? I think not and whoever was testing that at the end of the project should be sacked, or congratulated on the fact that he had some spare time because apparently all important work was finished. Unfortunately, this is rarely the case.

Instead, if the dev team has its' planning done right there is always some time available for a bug-squat-week.

Do not misunderstand me: I think those bugs should not be there. But the priority should be on quality assertion.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Death of a Devil

December 29, 2007 16:45 by Rob

According to this post, they finally decided to pull the plug. Netscape wil cease to exist.

In my early days our company made a lot of custom websites, and of course these sites needed to be crossbrowser compatible. Those were the days when IE 5 and NS 4 were the most recent browsers. Needles to say, the most difficult part of it was to make it work on Netscape. At that time, the implementations of JScript and DHTML were mostly inconsistent (to put it mildly).

The good stuff in this is that it reminded me of 'The Old Days', when building a site was just that.


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Hola Barcelona!

November 7, 2007 15:07 by Rob

This week I am attending the Microsoft TechEd Developers in Barcelona. Amongst the first impressions where those of dissappointment. First of all it is not that big as the ones I used to attend in Amsterdam. Secondly these seems to be no real new stuff. There is no new product hype. We've all been playing around with the beta's and CTP's of most products for a couple of months now, including Visual Studio 2008, the 3.5 .Net framework and Silverlight 1.1.

What strikes me most are the number of sessions on Silverlight that show basic stuff in 1.0. I attended a couple of sessions on how to communicate with the webserver from 1.0 Silverlight applications using Javascript and AJAX. Why should I want to do that? It will be phased out anyway as soon as 1.1 'hits the shelves'. Even more so, they already have native webservice support built in and working on SL1.1? I do not intend to spend my time working on code that'll be useless in a couple of weeks. Come on TechEd, bring the good stuff !!

This is of course all very reasonable, but the bottom line was reached when a speaker explained how to do c# a ternary operator on a lvl3 advanced course. This would've been fine if it didn't take him 10 minutes.

But the wheather is nice and the evenings are cool, so what am I complaining about?


Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5