Checking If the Browser Is Still Connected In ASP.NET

posted on 02/16/09 at 08:33:29 pm by Joel Ross

This past week, I had a bug assigned to me about a user canceling a long running process in their browser, but it kept running on the server. It was a process to generate PDF files, and the component we use is kind of memory intensive. As a result, having it run for no reason is troublesome. And of course, there's always the possibility that the user goes back and kicks off the process again, doubling the number of resources used.

There were a solution that immediately popped into my mind: make it asynchronous, and have a way to indicate to the user that it's done, and give them away to pick up the files on demand. This frees them up to move on to do other things, and solves the original problem. It's a good long term fix, and one we'll eventually move to.

But the question was more about being able to find a way to cancel the processing if the user left the page. Could we do that, deploy a quick fix that alleviated the resource hog, and give us some breathing room to implement the long-term fix?

It looks like the answer is yes. I hadn't run across it's usage very often before, but you can use Response.IsClientConnected to see if the browser is still waiting for the request to complete. You can check it periodically, and if the client has moved on, then you can cancel processing. In our case, we were generating a number of PDFs in a loop, so checking every time around worked fine, and the code is rather simple:

   1: public void GeneratePdfs()
   2: {
   3:     foreach(var pdf in PdfList)
   4:     {
   5:         // Get PDF Data and write it out
   7:         if (!Response.IsClientConnected) 
   8:         {
   9:             Response.End();
  10:         }
  11:     }
  13:     // Zip PDFs and send to browser.
  14: }

I wrote a quick test page to verify how it works, and fired up the debugger to watch the output window. Here was my Page_Load method:

   1: protected void Page_Load(object sender, EventArgs e)
   2: {
   3:     while (true)
   4:     {
   5:         if (Response.IsClientConnected)
   6:         {
   7:             Debug.WriteLine("Connected");
   8:         }
   9:         else
  10:         {
  11:             Debug.WriteLine("Disconnected");
  12:             break;
  13:         }
  14:     }
  15: }

Firing up the browser (I tested in IE and Firefox) and navigating to the page showed a steady stream of "Connected" in the output window. Closing the browser immediately wrote out "Disconnected", as did clicking back or navigating to another page. The only case I could find that didn't react as I'd expect was clicking stop or hitting escape on the page. It still showed as connected. Only after navigating to another page or closing the browser did it get the disconnected message. Still, in most cases, it's better than letting the process run it's course for no reason.

I know in this case, doing it asynchronously is the long term solution, but I'm sure in some cases, this will come in handy. And of course, I want to make sure it's the best way to handle it, so if you've done something similar, or better yet, better, what was it?

Categories: ASP.NET, C#


NFL Picks: 08-09 Super Bowl Pick

posted on 01/31/09 at 10:34:34 pm by Joel Ross

The time has finally come! Tomorrow, there will be a 5 hour (!) pre-game show, leading up to the single biggest sporting event of the year: The Super Bowl! This year, you have a team that's been there against a team that no one expected to get there.

Pittsburgh. The team that's been there, done that. This time without Jerome Bettis or The Jaw..err..I mean Bill Cowher. But they still have Big Ben and the best defense in the game.

Arizona. They've been underdogs the whole playoffs, in some games by as much as 10 points. They've put up over 30 in every game (leading the playoffs in scoring), and Larry Fitzgerald has proven that he's the real deal and ready to lead this team.

Something has to give, right? The best defense either breaks, or they shut down the hottest offense. And remember, Arizona is new to the Super Bowl spotlight, but their man under center has also been there, done that, has the MVP trophy to prove it.

Who to pick? It's a tough choice. Can the Cards overcome being the underdog again, and put up solid numbers and a lot of points, or will Pittsburgh shut Warner down, in typical suffocating fashion?

I'm going to go the boring route, and pick Pittsburgh. They're 7 point favorites, and have been since the line came out almost two weeks ago. A bit surprisingly, the over/under on this one is 46.5 points - pretty high for a game involving the Steelers. Given that, I'll take the under. I guess tomorrow at 6, we can all tune in and see how it turns out.

Or at least watch some good commercials!

Categories: Football


Using the Kinetic Framework with a Non-Table-Based Entity

posted on 01/23/09 at 12:28:34 am by Joel Ross

NuSoftFrameworkWhile I no longer work at RCM Technologies, I still watch the discussion forums for the Kinetic Framework. Recently, a question popped up, and since it’s gone unanswered for a few days, I figured I’d chime in. Essentially, the person is wondering if there’s a way to get an entity back that is based on several tables rather than the typical Active Record pattern used by default. The answer? Yes, you can do that.

As a matter of fact, I recently had the opportunity to do just that with a new feature we added to I'll talk about the new features over there in the future, but as part of one of the new things, we needed to have a virtual entity - it was based on data across a few tables.

As it turns out, this isn't that hard to accomplish. It also highlights some of the areas where some renaming is needed, but that's another story! Anyway, all you have to do is inherit from our read-only base class, add some attributes to the properties, override a method from the base, and ensure you structure your query to match your columns. Here's a contrived example that pulls data from a couple of tables and a user defined function, and puts it all into one entity:

   1: public class UserSummary : EntityBasereadOnly
   2: {
   3:     private string _userName;
   4:     [DatabaseColumn]
   5:     public string UserName
   6:     {
   7:         get { return _userName; }
   8:         set { _userName = value; }
   9:     }
  11:     private string _fullName;
  12:     [DatabaseColumn]
  13:     public string FullName
  14:     {
  15:         get { return _fullName; }
  16:         set { _fullName = value; }
  17:     }
  19:     private int _orderCount;
  20:     [DatabaseColumn]
  21:     public int OrderCount
  22:     {
  23:         get { return _orderCount; }
  24:         set { _orderCount = value; }
  25:     }
  27:     public static EntityListReadOnly<UserSummary> GetUserSummaries()
  28:     {
  29:         string commandText = @"
  30:                                 select u.UserName,
  31:                                        up.FirstName + ' ' + up.LastName as 'FullName',
  32:                                        dbo.GetOrderCount(u.UserId) as 'OrderCount'
  33:                                 from Users u 
  34:                                 inner join up 
  35:                                  on u.UserId = up.UserId
  36:         ";
  38:         return EntityBaseReadOnly
  39:             .GetListReadOnly<UserSummary>(commandText, new List<SqlParameter>());
  40:     }
  42:     protected override void EnsureParentProperties() { }
  43: }

There's one major thing to notice here: the use of the [DatabaseColumn] attribute on the properties. As long as the columns returned by your query match up with the property name in your query, then when you call EntityBaseReadOnly.GetListReadOnly(), it will be able to populate your entity automatically. Since this inherits from EntityBaseReadOnly, this entity can't be saved, which in most cases is just fine.

Categories: Development, C#


NFL Picks: 08-09 Divisional Results and Conference Final Picks

posted on 01/16/09 at 11:50:28 pm by Joel Ross

The end of the NFL playoffs is always bittersweet. The games mean more and more, but it also means that soon, there'll be no more games. We're down to three games left as it is! This past week had some good games, so let's take a look.

  • Baltimore 13, Tennessee 10 (-3) (34.5 O/U): This was a defensive struggle, and I Tennessee basically handed this game over. Kind of disappointing, considering that at one point we were looking at Tennessee as the team to beat when they were undefeated. Of course, it's not a huge surprise, considering that these two teams played in week 5. The outcome of that game? 13-10, only Tennessee ended up on top.
  • Arizona 33, Carolina 13 (-10) (48 O/U): This game wasn't ever really a game. Carolina was outplayed pretty much from the kickoff, and Arizona, even without Boldin, never looked back.
  • Philadelphia 23, New York Giants 11 (-4) (40.5 O/U): Another sloppy game. Remember me saying that 75% of the home teams win in the playoffs when they're coming off a bye week? Yeah, that didn't quite happen, did it?
  • San Diego 24, Pittsburgh 35 (-6) (39 O/U): Pittsburgh was the only team to come through who was a favorite, and they did it pretty decisively. I'd say they are the favorite to win it all at this point.

Results Summary

  • Picks (this week / playoffs): 1 - 3 / 3 - 5
  • Spread (this week / playoffs): 1 - 3 / 3 - 5
  • Over/Under (this week / playoffs): 2 - 2 / 3 - 5

I'd definitely say that one conference is looking a lot stronger than the other at this point, but that doesn't mean much does it? Remember, last year, New England couldn't lose and they were facing either a team with an aging QA (the Packers) or a QB who chokes in the big games (the Giants). And we all now how that turned out.

  • Philadelphia (-4) vs. Arizona (47 O/U): Philly is the obvious choice. They have the experience. They're the better team. They're the favorite. But you could say the same thing last week and Carolina too, right?
  • Baltimore vs. Pittsburgh (-6) (34 O/U): These teams have met twice this season - early in the season and again later in the season. The outcomes? Pittsburgh won by 4 and 3. Both were low scoring, defensive battles. I'd expect this game to only appeal to fans of their teams, and hardcore football enthusiasts who understand the importance of battles for field position. If you want a high scoring game, watch the NFC!

Sunday night, we'll know who's in the Super Bowl. Then the media circus really starts!

Tags: | |

Categories: Football


Managing Static Files & Browser Caching

posted on 01/14/09 at 12:26:48 am by Joel Ross

As a web developer, if you have a static file, and it gets updated, how do you ensure that it gets downloaded by your users, instead of using the previously cached version?

That's the problem I was faced with the other day. I had a JavaScript file that I was updating, and trying to figure out the best way to ensure it got refreshed on the client-side. We'd been using a couple of different methods, but they required manual steps to get them working:

  1. Rename the file. If I had a file named app.js, I could rename that to app_001.js. Then app_002.js, etc.
  2. Add a query string to the file. Reference the file in the page as app.js?version=001. Then app.js?version=002.

Both of the above solutions work. But they have issues. They're both manual, and have to be 1.) remembered each time the file is changed, and 2.) well known by every team member.

The other downside is that every place that file is referenced in the code needs to be updated. For most files like that, they're referenced in one place, but sometimes (especially as the project grows) things get out of hand, and it will get referenced in multiple places. So, after talking through the problem, I think we came up with a nice solution. It accomplishes two goals - it centralizes the references of the files (without being too invasive on existing code), and automates the process of telling the browser to grab a new version when the file is updated.

So how does it work? Let's look at some code. I created a new class called JavascriptUrlBuilder to do the work for me. It takes in a string, checks the timestamp of the file, and tacks that onto the querystring. Then it caches that information so subsequent requests don't have to hit the file system every time. Here's the actual code:

   1:  public class JavascriptUrlBuilder
   2:  {
   3:     private static object _syncObject = new object();
   5:     public static string GetUrlFor(string javascriptFile)
   6:     {
   7:        if(HttpContext.Current.Cache[javascriptFile] == null)
   8:        {
   9:           lock(_syncObject)
  10:           {
  11:              if(HttpContext.Current.Cache[javascriptFile] == null)
  12:              {
  13:                 var fileInfo = new FileInfo(HttpContext.Current.Server.MapPath(javascriptFile));
  14:                 var filePath = String.Format({0}?v={1}{2}{3}{4}{5}{6}",
  15:                                       VirtualPathUtility.ToAbsolute(javascriptFile),
  16:                                                   fileInfo.LastWriteTimeUtc.Year.ToString("0000"),
  17:                                                   fileInfo.LastWriteTimeUtc.Month.ToString("00"),
  18:                                                   fileInfo.LastWriteTimeUtc.Day.ToString("00"),
  19:                                                   fileInfo.LastWriteTimeUtc.Hour.ToString("00"),
  20:                                                   fileInfo.LastWriteTimeUtc.Minute.ToString("00"),
  21:                                                   fileInfo.LastWriteTimeUtc.Second.ToString("00"));
  22:                 HttpContext.Current.Cache.Insert(javascriptFile, 
  23:                                          filePath, 
  24:                                          new CacheDependency(fileInfo.FullName));
  25:              }
  26:           }
  27:        }
  29:        return HttpContext.Current.Cache[javascriptFile].ToString();
  30:     }
  31:  }

The nice part is that it uses a cache dependency on the file system, so anytime the file is updated, the cache gets evicted, and you get a new timestamp, thus forcing browsers to re-download the file.

To use it, it's as simple as this:

   1:  this.ClientScript
   2:      . RegisterClientScriptInclude(this.GetType(), 
   3:                             "jquery", 
   4:                             JavascriptUrlBuilder.GetUrlFor(JavascriptFiles.JQuery));

You'll also notice that I've created a class with a set of constants that define all of the different JavaScript files we have, making it easy to know what's available, and maintaining all of them in one place.

By doing this, we've accomplished both goals we set out to do: browsers will always have the latest files without any manual steps for the developers, and it centralizes how the files are referenced. Yes, you can still add them to a page where ever you want, but if I ever need to change the name of a file (for example, from jquery-1.2.6.js to the next rev), I just change the one reference, and all of them get updated automatically.

I'm sure there's a better way to handle this, but this works and is relatively automated. What have you done to handle this issue?

Categories: Development, C#


NFL Picks: 08-09 Wildcard Results and Divisional Picks

posted on 01/10/09 at 12:23:47 am by Joel Ross

Last week was a pretty good week of football, and showed one thing: It's time for college-style OTs!

  • Atlanta 24 (-1.5), Arizona 30 (51.5 O/U)
  • Indianapolis 17 (-1), San Diego 23 (51 O/U)
  • Baltimore 27 (-3), Miami 9 (37.5 O/U)
  • Philadelphia 26 (-3), Minnesota 14 (42 O/U)

Results Summary

  • Picks: 2 - 2
  • Spread: 2 - 2
  • Over/Under: 1 - 3

Not a great week for me, picks wise. Let's see if next week is any better.

  • Baltimore vs. Tennessee (-3) (34.5 O/U)
  • Arizona vs. Carolina (-10) (48 O/U)
  • Philadelphia vs. New York Giants (-4) (40.5 O/U)
  • San Diego vs. Pittsburgh (-6) (39 O/U)

Should be some good games this week. But remember, this week of the playoffs, the home team wins about 75% of the time. The safest bet (as I did) is to always pick the home team.

Tags: | |

Categories: Football


NFL Picks: 08-09 Week 17 Results and Wildcard Picks

posted on 01/02/09 at 11:02:32 pm by Joel Ross

The playoffs are finally here! It's bittersweet, really. While the games get better, there's only 11 games left in the season! Anyway, let's review the final week.

  • St. Louis* 27, Atlanta 31 (-14) (44.5 O/U)
  • Jacksonville* 7, Baltimore 27 (-12.5) (37.5 O/U)
  • New England 13 (-6), Buffalo 0 (40 O/U)
  • Kansas City 6, Cincinnati 16 (-3) (38.5 O/U)
  • Detroit* 21, Green Bay 31 (-10.5) (43 O/U)
  • Chicago 24, Houston 31 (-2.5) (46.5 O/U)
  • Tennessee 0 (-3), Indianapolis 23 (38.5 O/U)
  • New York Giants* 19, Minnesota 20 (-7) (42 O/U)
  • Carolina 33 (-2.5), New Orleans 31 (51.5 O/U)
  • Miami 24, New York Jets 17 (-2.5) (42 O/U)
  • Dallas 6, Philadelphia 44 (-1.5) (42.5 O/U)
  • Cleveland 0, Pittsburgh 31 (-11) (34 O/U)
  • Oakland* 31, Tampa Bay 24 (-13) (39.5 O/U)
  • Seattle 21, Arizona 34 (-7) (45.5 O/U)
  • Denver 21, San Diego 52 (-8) (50.5 O/U): This was an awesome game to have on Sunday night. It was the final game of the season, and it had tremendous meaning to the playoffs - you win and you're in. It was like getting an extra playoff game!
  • Washington 24, San Francisco 27 (-3) (37.5 O/U)

Results Summary

  • Picks (this week / season): 11 - 5 / 161 - 95
  • Spread (this week / season): 12 - 3 / 128 - 119
  • Over/Under (this week / season): 4 - 12 / 128 - 121

And on to the playoff picks!

  • Atlanta (-1.5) vs. Arizona (51.5 O/U): Atlanta is one of the hottest teams in the NFL right now, while Arizona sort of skidded across the finish line.
  • Indianapolis (-1) vs. San Diego (51 O/U): Payton Manning just got league MVP (again). His team is hot.
  • Baltimore (-3) vs. Miami (37.5 O/U)
  • Philadelphia (-3) vs. Minnesota (42 O/U)

I think this is the first time I've ever seen all four away teams as the favorites in a playoff round. Should be a good weekend for football!

Tags: | |

Categories: Football


NFL Picks: 08-09 Week 16 Results and Week 17 Picks

posted on 12/26/08 at 11:21:35 pm by Joel Ross

It's the final week of the regular season, and it's Christmas week! Awesome combo. Anyway, on to last week's results.

  • Indianapolis 31 (-6), Jacksonville 24 (44 O/U)
  • Baltimore 33, Dallas 24 (-4) (39.5 O/U)
  • Cincinnati 14, Cleveland 0 (-3) (32 O/U)
  • New Orleans 42 (-7), Detroit 7 (50.5 O/U)
  • Miami 38 (-4), Kansas City 31 (40 O/U)
  • Atlanta 24, Minnesota 17 (-3) (43.5 O/U)
  • Arizona 7, New England 47 (-7.5) (45.5 O/U)
  • Carolina 28, New York Giants 34 (-3) (37.5 O/U)
  • San Francisco 17, St. Louis 16 (-5.5) (43.5 O/U)
  • Pittsburgh 14 (-2), Tennessee 31 (34.5 O/U): I wonder if either team held back anything in anticipation of a playoff re-match?
  • Philadelphia 3 (-5), Washington 10 (38.5 O/U)
  • Buffalo 30, Denver 23 (-6.5) (45 O/U)
  • Houston 16 (-7), Oakland 27 (44 O/U)
  • New York Jets 3 (-5), Seattle 13 (44 O/U)
  • San Diego 41, Tampa Bay 24 (-3) (42.5 O/U)
  • Green Bay 17, Chicago 20 (-4) (41 O/U)

Results Summary

  • Picks (this week / season): 7 - 9 / 150 - 90
  • Spread (this week / season): 8 - 8 / 116 - 116
  • Over/Under (this week / season): 11 - 5 / 124 - 109

And now it's time for the last regular season picks for the season!

  • St. Louis* vs. Atlanta (-14) (44.5 O/U)
  • Jacksonville* vs. Baltimore (-12.5) (37.5 O/U)
  • New England (-6) vs. Buffalo (40 O/U)
  • Kansas City vs. Cincinnati (-3) (38.5 O/U): How many people care about this game?
  • Detroit* vs. Green Bay (-10.5) (43 O/U): A meaningless game, that could be historic (at least for Detroit)
  • Chicago vs. Houston (-2.5) (46.5 O/U)
  • Tennessee (-3) vs. Indianapolis (38.5 O/U): This could be another preview of a playoff match up. If I were Indy, I think I'd hold some of the playbook back so Tennessee doesn't get to see everything first hand.
  • New York Giants* vs. Minnesota (-7) (42 O/U)
  • Carolina (-2.5) vs. New Orleans (51.5 O/U)
  • Miami vs. New York Jets (-2.5) (42 O/U)
  • Dallas vs. Philadelphia (-1.5) (42.5 O/U)
  • Cleveland vs. Pittsburgh (-11) (34 O/U)
  • Oakland* vs. Tampa Bay (-13) (39.5 O/U)
  • Seattle vs. Arizona (-7) (45.5 O/U)
  • Denver vs. San Diego (-8) (50.5 O/U)
  • Washington vs. San Francisco (-3) (37.5 O/U)

Should be a good week. Playoff match ups will be finalized by Sunday night, and then the real season starts!

Tags: | |

Categories: Football


NFL Picks: Week 15 Results and Week 16 Picks

posted on 12/19/08 at 12:40:11 am by Joel Ross

This is a bit late, but I made my picks long before the game started tonight!

  • New Orleans 24, Chicago 27 (-3) (45 O/U)
  • Tampa Bay 10, Atlanta 13 (-3) (44.5 O/U)
  • Pittsburgh 13, Baltimore 9 (-2) (34.5 O/U): The best defense against the best home team defense. Yeah, that explains the low scoring game.
  • Denver 10, Carolina 30 (-7.5) (47.5 O/U)
  • Washington 13 (-7), Cincinnati 20 (36.5 O/U)
  • Tennessee 12 (-3), Houston 13 (44.5 O/U): Someone remind Tennessee where they were a month ago.
  • Detroit 21, Indianapolis 31 (-17) (45 O/U)
  • Green Bay 16 (-1.5), Jacksonville 20 (45 O/U)
  • San Diego 22 (-5.5), Kansas City 21 (45.5 O/U)
  • San Francisco 9, Miami 14 (-6.5) (41.5 O/U)
  • Buffalo 27, New York Jets 31 (-7.5) (41 O/U)
  • Seattle 23 (-3), St. Louis 20 (44 O/U)
  • Minnesota 35, Arizona 14 (-3) (41 O/U)
  • New England 49 (-7), Oakland 26 (40 O/U)
  • New York Giants 9, Dallas 20 (-3) (45 O/U)
  • Cleveland 10, Philadelphia 30 (-14) (38.5 O/U)

Results Summary

  • Picks (this week / season): 10 - 6 / 143 - 81
  • Spread (this week / season): 4 - 9 / 108 - 108
  • Over/Under (this week / season): 8 - 8 / 113 - 104

On to this week's picks

  • Indianapolis (-6) vs. Jacksonville (44 O/U)
  • Baltimore vs. Dallas (-4) (39.5 O/U)
  • Cincinnati vs. Cleveland (-3) (32 O/U): I suppose someone has to win, right?
  • New Orleans (-7) vs. Detroit (50.5 O/U)
  • Miami (-4) vs. Kansas City (40 O/U)
  • Atlanta vs. Minnesota (-3) (43.5 O/U)
  • Arizona vs. New England (-7.5) (45.5 O/U)
  • Carolina vs. New York Giants (-3) (37.5 O/U)
  • San Francisco vs. St. Louis (-5.5) (43.5 O/U)
  • Pittsburgh (-2) vs. Tennessee (34.5 O/U): Pittsburgh is looking really good, and Tennessee? Well, they lost to Houston.
  • Philadelphia (-5) vs. Washington (38.5 O/U)
  • Buffalo vs. Denver (-6.5) (45 O/U)
  • Houston (-7) vs. Oakland (44 O/U)
  • New York Jets (-5) vs. Seattle (44 O/U)
  • San Diego vs. Tampa Bay (-3) (42.5 O/U)
  • Green Bay vs. Chicago (-4) (41 O/U)

Check back next week for results, and my final regular season picks.

Tags: | |

Categories: Football


Balsamiq: Easy UI Mockups

posted on 12/11/08 at 08:59:55 pm by Joel Ross

About a week ago, I was finally to a point where I was ready to take on a new feature at TrackAbout on my own. Well, it was just one screen, but it was a fairly complex screen, so I was asked to come up with an idea of what I thought it should look like. In the past, I've done mock ups in the past, but before diving into the pain that is Visio, I decided to ask our team what we've used in the past.

Joey said he'd been happy with Balsamiq, so I decided to give it a look. I was immediately impressed. It was so easy to use, and much, much more intuitive than what I was used to. In less than an hour, I was able to create mock ups for my screen in 4 different states.

Then, when I needed to make updates the next day, it was as simple as importing an XML document to get back to where I was the day before. Oh yeah. Did I mention I did this all online in a browser? Yeah - no software to install and all in the browser. They have lots of controls you can use, and it's all drag and drop. They've even added keyboard shortcut support, so things like copying, pasting and selecting work just like they would in a desktop application.

Since I can't really show what I actually designed, I spent 5 minutes creating a simple mock up of - guess? - a bracket, much like we have on Tourneytopia. Here's what I came up with:


It's all drag and drop, and you can quickly get a realistic mockup going in very little time. It's definitely a tool I will be using in the future when I need to layout new user interfaces.

Tags: | |

Categories: Software


<< 1 2 3 4 5 6 7 8 9 10 11 ... 124 >>