DCSIMG
Pini Dayan

Pini Dayan

The best thing about a boolean is even if you are wrong, you are only off by a bit.

JavaScript Callee property

Hi all,

It always amazes me how I discover another JavaScript feature I wasn’t aware of. The feature I want to discuss here in this post is the Callee property we have from the arguments property we have when we are in a function scope.

This property will return the current function being executed right now. In addition we have the caller property that we can use to get a reference to the calling function.Imagine you could even do crazy stuff like getting the caller function and its argument by doing something like:

arguments.callee.caller.arguments[0].

Here for example we are doing something nice:

image

Not every browser support this property although it was omitted by ECMA

How to easily search SQL stored procedures and objects

Hi all, Lately I have been working on a Migration project in which I had to move data from an old SQL DB into a new one with a different schema (slightly different). In order to understand the differences I downloaded several free tool in which I could compare both schema. There are lots of good tool for that but during the project I also had to look out for things like:

1. Which stored procedures and Tables FK uses a given column?

2. Which tables contains a given ID

and much much more questions of that kind. So instead of using a stored procedures and system tables to perform the task I have found out that there is a free tool from the “Redgate” company that does exactly that:It is called “SQL Search” and here are some snap shots to let you understand how it works.  (BTW it is fully integrated with SQL management studio 2005, 2008).

image

(You can filter which object types you want to search in : Tables, SP, Views etc)

image

Once clicked you can see the text and move to the SP.

image

Here is the link for the download:http://www.red-gate.com/products/SQL_Search/index.htm

Enjoy!

Posted: Oct 26 2010, 09:57 AM by Pini Dayan | with 2 comment(s) |
תגים:,

ASP.NET Ajax 4/3.5 CDN support

Today I found out a cool nice thing. As we all know Microsoft ASP.NET Ajax 4.0 is shipped with the new caching support for the JS library it uses. This feature is called the CDN and basically it is working and increasing performance by spreading lots of servers around the world that store JS files like the ASP.NET Ajax 4.0 and the Jquery library files.

From Microsoft: “By taking advantage of the Microsoft Ajax CDN, you can significantly improve the performance of your Ajax applications. The contents of the Microsoft Ajax CDN are cached on servers located around the world”

For a list of all available files check this site.

What if your application is ASP.NET 3.5 and not 4.0 and you are not using or whishing to upgrade to the 4.0 version. Well you can still use the CDN. Microsoft added the 3.5 Js files to the CDN as well.

The 2 files available are the

 http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.debug.js

 http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.js

You can use them by using the Script manager like this:

<asp:ScriptManager ID="SCRIPTMANAGER1" EnablePartialRendering="false" runat="server">

 <Scripts>

     <asp:ScriptReference Name="MicrosoftAjax.js"

                Path="http://ajax.microsoft.com/ajax/3.5/MicrosoftAjax.js" />               

 </Scripts>

</asp:ScriptManager>

Enjoy

Adding/Firing custom event using JavaScript

Today I found out a very cool way for adding custom events and fire them for any Client side object. This can be done using ASP.NET Ajax very easily. (Thank you Igor).

In order to create these events and fire them we will use the Sys.EventHandlerList Class. This class Creates a dictionary of client events for a component, with event names as keys and the associated handlers as values. It’s main method we need are the addHandler and getHandler. Lets see a simple example which is pretty self explanatory.

This sample creates a Book and a Library “classes”. The Library class will have a Add and a GetBook method that will fire an event when ever they are called. Here is the Code: (And again it is pretty self explanatory)

   11 <form id="form1" runat="server">

   12     <asp:ScriptManager runat=server ID="SM">

   13     </asp:ScriptManager>

   14     <div>

   15 

   16     </div>

   17 

   18       <script>

   19           function Enums() {

   21               throw Error.notImplemented();

   22           }

   23 

   24          Enums.ActionType = { Add: "Add", Get: "Get" }

   26 

   27 

   28           function Book(name) {

   29               this.Name = name;

   30           }

   31 

   32           function Library() {

   33               this.Books = [];

   34           }

   35 

   36           Library.prototype.Add = function(book) {

   37               this.Books[this.Books.length] = book;

   38 

   39               this.fireEvent(Enums.ActionType.Add, book);

   40           }

   41 

   42           Library.prototype.GetBook = function(bookName) {

   43               var retval = null;

   44               for (var x = 0; x < this.Books.length; x++) {

   45                   if (this.Books[x].Name == bookName) {

   46                       retval = this.Books[x];

   47                   }

   48               }

   49               this.fireEvent(Enums.ActionType.Get, retval);

   50               return retval;

   51           }

   52 

   53           Library.prototype.addHandler = function(eventId, handler) {

   54               if (!this._events) {

   55                   this._events = new Sys.EventHandlerList();

   56               }

   57               this._events.addHandler(eventId, handler);

   58           }

   59 

   60           Library.prototype.fireEvent = function(eventId, book) {

   61               var events = this._events;

   62               if (!events) {

   63                   return false;

   64               }

   65 

   66               var handler = events.getHandler(eventId);

   67               if (handler) {

   68                   handler(book);

   69               }

   70           }

   71 

   72           var lib = new Library();

   73           lib.addHandler(Enums.ActionType.Add, BookAdded);

   74           lib.addHandler(Enums.ActionType.Get, BookUpdated);

   75 

   76 

   77           function BookAdded(book) {

   78               alert("A book was added:" + book.Name);

   79           }

   80 

   81           function BookUpdated(book) {

   82               alert("A book was updated:" + book.Name);

   83           }

   84 

   85           lib.Add(new Book("C# book"));

   86           lib.Add(new Book("VB.NET book"));

   87           lib.GetBook("C# book");

   88 

   89 

   90     </script>       

   91     </form>

Enjoy.

Ever forgot “alert()” when deployed to production

As developers we often forget to remove debug code on the client side such as “alert” calls , “debugger” statements and so on. So in order to avoid our team leader throw a chair at us here is a simple solution to this problem:

On the page startup ( page load or when ever you find it necessary) simply override the alert method like this:

Set alert to work only in debug

var originalAler = window.alert;

window.alert = function(message) {

if (Sys.Debug.isDebug) {

   originalAler(message);

}

}

What i am doing here is to save the original alert method in a variable(delegate) and when someone uses the alert message simply check if we are in debug mode (I used ASP.NET Ajax) and call the original alert.

Enjoy.

 

Using C# 4 to implement lazy initialization

Sometimes we wish to improve performance and improve memory usage by making sure the Object we create and initialize is really needed. A couple of scenarios that we might thing of are:

  • We have an object that is expensive to create and there might be situations when we don't really need it. Lets say we have an Employee object in memory and this Employee has a property by the name FormerEmployers that describe all the places he worked at. This information is initialized from a DB. If the consumer of this Employee object never reading this data there is no sense filling the memory and bringing this data.

  • We have an expensive Object to create but we want it’s creation only after other expensive objects have created. An example for this is a creation of some large arrays or lists when the application first loads but the other are not necessary immediately.

Up until now days we had to implement this laziness by ourselves. Now we can use the Lazy<T> within .NET 4.

Her are some samples and expiations from MSDN:

To define a lazy-initialized type, for example, MyType, use Lazy<MyType> (Lazy(Of MyType) in Visual Basic), as shown in the following example. If no delegate is passed in the Lazy<T> constructor, the wrapped type is created by using ActivatorCreateInstance() when the value property is first accessed. If the type does not have a default constructor, a run-time exception is thrown.

// Initialize by invoking a specific constructor on Order when Value

// property is accessed

Lazy<Orders> _orders = new Lazy<Orders>(() => new Orders(100));

You can also pass a delegate in the Lazy<T> constructor that invokes a specific constructor overload on the wrapped type at creation time, and perform any other initialization steps that are required, as shown in the following example.

// Initialize by invoking a specific constructor on Order when Value

// property is accessed

Lazy<Orders> _orders = new Lazy<Orders>(() => new Orders(100));

After the Lazy object is created, no instance of Orders is created until the Value property of the Lazy variable is accessed for the first time. On first access, the wrapped type is created and returned, and stored for any future access.

// We need to create the array only if displayOrders is true

if (displayOrders == true)

{

     DisplayOrders(_orders.Value.OrderData);

}

else

{

    // Don't waste resources getting order data.

}

Thread–safe Initialization

Some Lazy<T> constructor overloads have a Boolean parameter named isThreadSafe that is used to specify whether the Value property will be accessed from multiple threads. If you intend to access the property from just one thread, pass in false to obtain a modest performance benefit. If you intend to access the property from multiple threads, pass in true to instruct the Lazy instance to correctly handle race conditions in which one thread throws an exception at initialization time. If you use a constructor that does not have the isThreadSafe parameter, the value defaults to true.

In multi-threaded scenarios, the first thread to access the Value property initializes it for all subsequent accesses on all threads, and all threads share the same data. Therefore, it does not matter which thread initializes the object, and race conditions are benign. If the first thread to initialize Value causes an exception to be thrown, that same exception will be thrown for all subsequent accesses of Value. It is not possible for one thread to raise an exception and another to initialize the object. The following example shows that the same Lazy<int> instance has the same value for three separate threads.

 

// Initialize the integer to the managed thread id of the

// first thread that accesses the Value property.

Lazy<int> number = new Lazy<int>(() => Thread.CurrentThread.ManagedThreadId);

Thread t1 = new Thread(() => Console.WriteLine("number on t1 = {0} ThreadID = {1}",

                                                number.Value,

                                                Thread.CurrentThread.ManagedThreadId));

t1.Start();

Thread t2 = new Thread(() => Console.WriteLine("number on t2 = {0} ThreadID = {1}",

                                               number.Value,

                                               Thread.CurrentThread.ManagedThreadId));

t2.Start();

Thread t3 = new Thread(() => Console.WriteLine("number on t3 = {0} ThreadID = {1}",

                                               number.Value,

                                               Thread.CurrentThread.ManagedThreadId));

t3.Start();

//Ensure that thread IDs are not recycled if the

//first thread completes before the last one starts.

t1.Join();

t2.Join();

t3.Join();

Enjoy :-)

Posted: Apr 08 2010, 10:02 AM by Pini Dayan | with 2 comment(s) |
תגים:,

ASP.NET 4.0 New features – HTML, JS, ASP.NET Snippets

                                            image

In previous version of VS.NET we encountered the new snippet solution for creating a chunk of code that is usually reusable and then using it during programming or even lecturing. This feature was available for both C# and VB.NET coders. But we could not create or use snippets for the markup we are writing like HTML, JavaScript or even the ASP.NET page. VS.NET 2010 allows us to do just that!

Lets see some of the “out of the box” snippets we can use:

HTML Snippets:

image 

 

AS you can see the same snippet sign is now available on the ASPX page side.  So for example if I choose the checkbox snippet and double tab click it i will get the following markup:

image

JavaScript Snippets:

Let move even further and see a much useful sample. Most of us are writing JavaScript and lots of it in our web application, so lets see what is available out of the box for us in JavaScript :

alert snippet,control snippet,create snippet, do for while snippets, if else snippets and much much more. Here for example I am using the for snippet for creating a for clause.

image

ASP.NET snippets:

We have some useful control declarations as a snippets such as updatepanel, sqldatasource , all the validator controls and much much more.

Creating our own custom snippets:

Wouldn’t it be great to create our own snippets since we are the ones knowing what markup we most commonly using. So before showing how to accomplish this, Here is how you can see the entire list of snippets.

In the VS.NET 2010 , clicj the tool menu and open the “code  snippets manager”
image 

This snippet manager will now show you all the HTML, ASP.NET snippets or the JS snippets if you choose Jscript in the language select box. So in order to add them simply use this manager and read how to create the snippet files here.

Surround with feature:

Another cool thing we have in C# and is really useful is the “surround with” . We can for example write some JS code and then decide we want to surround it with a function. Simply select the wanted Js , right click and choose “surround with” .

Enjoy.

ASP.NET 4.0 New features – URL Routing

                                               image

Hi all, In this series of posts I am going to write about ASP.NET 4.0 new features. I will try to concentrate on the important features since there are many new cool ones. At this point of writing I am using the VS.NET 2010 Ultimate Beta 2 version. So lets introduce the first feature:

URL Routing:                  

URL Routing is the ability to use “friendly” URL’s instead of of using the once we know so far. So instead of using the knows URL’s like:

http://www3.cet.ac.il/FieldsPage.aspx?ID=Science

http://www.google.com/search?q=vs.net+2010&rls=com.microsoft:en-us&ie=UTF-8&oe=UTF-8&startIndex=&startPage=1

where we have a protocol , a host name , a directory list, a page and a query string in the format: field1=value1&field2=value2&field3=value3...

We can use a “friendlier” version like:

http://www.Developers.com/software/aspnet

These “friendly” URL’s has the following benefits:

  1. They are more readable ( Actually it is debatable but lets go with the flow)  
  2. They are more SEO friendly (Search engine optimization)

The idea is to map these URL’s to a physical files by configuring your application. Up until now, this feature existed in ASP.NET MVC, now we can use it in ASP.NET 4.0. So how do we do it and where do we do it:

All we need to do is adding the routing data some where in the application , A good place to do it is in the Application_Start event so it will happen only once. Here is a sample code that demonstrate how to achieve the routing:

 

Adding routing to the global.asax:

 

 

protected void Application_Start(object sender, EventArgs e)
{
  //Routes: An object of type RouteCollection that contains all the routes
  ConfigureSiteURLRouting(System.Web.Routing.RouteTable.Routes);
}

private void ConfigureSiteURLRouting(System.Web.Routing.RouteCollection routeCollection)
{
  routeCollection.MapPageRoute("RouteCategory",       // A friendly name to descrive the route
                               "Books/{bookName}",    // The url format
                               "~/Book.aspx");        // The actual web page to handle the request

}

Getting the url values in the destination page:

Now once I am navigating to http://localhost:1559/Books/ASPNET in my development environment I am actually running the page “book.aspx” which has the following code for getting the book parameter:

string bookName = Page.RouteData.Values["bookName"] as string;

Programmatically Generating outgoing URL’s :

Just like we can map incoming URL’s to our real pages, we can generate them for the outgoing request as well. So in order to generate a URL in the following format  we can use the Page.GetRouteUrl method to perform just that.

Enjoy

 

Ajax ToolKit:Fix ResizableControl handler position problem

One of the controls available in the Ajax ToolKit is the ResizableControlExtender which makes a panel (div) resizable. One of the major bugs this control has his the ability to set the location for the handler (The place holder for the mouse with the resize cursor) to the left bottom corner of the ResizableControl target. There are many solutions out there , but as I tried them most of them simply do not solve the problem. After downloading the ResizableControlBehavior.js file and learning how it works , here is a simple solution to the problem:

1. Set the HandleOffsetY and HandleOffsetX properties of the ResizableControlExtender control to 3.

2. During this point the handler will be set in the top right corner as the following code from the ResizableControlBehavior.js  indicates: 

  // The this._handleHolder provedes a wrapper with absolute positioning

  // so that this._handle can be absolutely positioned relative to the

  // this._frame instead of the page

  this._handleHolder = document.createElement('DIV');

  this._handleHolder.style.width = '0px';

  this._handleHolder.style.height = '0px';

  this._handleHolder.style.position = ((Sys.Browser.agent === Sys.Browser.Opera) ?

    'relative' : 'absolute');

  this._frame.insertBefore(this._handleHolder, this._frame.firstChild);

 

  // The this._handle represents the UI handle for the user to grab with

  // the mouse

  this._handle = document.createElement('DIV');

  this._handle.className = this._HandleCssClass;

  this._handle.style.position = 'absolute';

  this._handleHolder.appendChild(this._handle);

 

3. So all we need to do is fix the _handler position:

 

  //Get control using the behaviour id

  var resizeControl = $find("ResizableControlExtenderBehavior1");

 

  //Get initial left and top of the handler

  var handlerInitialLeft = resizeControl._handle.style.left;

  var handlerInitialTop = resizeControl._handle.style.top;

 

 //Get the width and height of the resizable control

 var myPanel = $get(GetdivParticipantsID());

 var myPanelWidth = parseInt(myPanel .style.width.replace("px", "")) - 10;

var myPanelHeight = parseInt(myPanel .style.height.replace("px", "")) - 10;

 

//Change the handlers location

resizeControl._handle.style.left = (parseInt(handlerInitialLeft.replace("px", ""), 10) 

                                                 myPanelWidth ) + "px";

resizeControl._handle.style.top = (parseInt(handlerInitialTop.replace("px", ""), 10) +

                                                myPanelHeight ) + "px";

 

Enjoy.

Ajax Tip: Set position for ModalPopupExtender

Hi all, Ever wanted to set the location of the Modal windows you open using the ModalPopupExtender available when using ASP.NET Ajax toolkit?

Well there is a very simple way to do it using BLOCKED SCRIPT

1. Get the position you want the modal window to show. You can do it using ASP.NET Ajax library using Sys.UI.DomElement.getLocation method like this:

var location = Sys.UI.DomElement.getLocation($get("div1")); 

In this case I used some div control to set the modal windows next to it.

2. Get the Modal window reference by using it’s panel or div element.

3. Set the location of the modal window:

    Sys.UI.DomElement.setLocation($get(‘panel1’), location.x,

                                                         location.y);     

 


Enjoy

Microsoft ASP.NET Ajax DOM Events

Hi all, Lately I add to deal with a lot of cross browser stuff (Needless to say is is very ugly and in frustration times I wish we only had IE :-) )

Anyway , one cool way to solve lots of these issues is of course to use a Framework that does all the Cross browser JS for you.I am using Microsoft ASP.NET Ajax Library. Here is a nice example of how to handle mouse clicks in a way that will work on IE, Chrome and Firefox.

When trying to work with the mouse event (And writing cross browser code) you get familiar with the phrase :”JavaScript Madness”. For example: When wanting to know which mouse button was clicked and we want to use the “event” object JavaScript offers we see there is little cross browser compatibility regarding the number representing which button was clicked. In IE we have “event.button” with the values of 1, 4, 2 but we don’t have “event.which” which works for Safari Netscape and some other browsers. The “event.which” value was originally used in Netscape, and the “event.button” value was originally used in Internet Explorer. Later browsers used both, and messed them both up.

So here is a Sample code to illustrate how simple it is when using the framework and the DOM options it provides:

<script>

function pageLoad(sender, args) {

    //Attach the onmousedown to a div

    Sys.UI.DomEvent.addHandler($get("divMoustDown"), "mousedown", ShowContextMenu);

}

 

function ShowContextMenu(e) {

  if (e.button == Sys.UI.MouseButton.rightButton)

  {

    alert("Right button was clicked");

   }

   else if (e.button == Sys.UI.MouseButton.leftButton)

   {

    alert("Left button was clicked");

   }

   else {

       alert("Middle button was clicked");

   }

}   

</script>

You can read more on the JavaScript mouse problems here: Mouse Events

And the Sys.UI namespace here : ASP.NET Ajax Client reference.

RoundedCorners control – how does it really work?

ASP.NET Ajax toolkit has many cool controls, one of them is the RoundedCorners control. I think any ASP.NET developer meets the problem of how to create a control with rounded corners sometime during his career. Most of us solve this issue using images by creating 4 images , one for each corner. Here is a good example of how to achieve this using image and table.

There is another solution that is not yet cross browser one. there is the css 3 new upcoming feature for giving each control a raduis. Mozilla already supports it and calls it “moz-border-radius”, I even wrote about it in my blog:CSS 3 new amazing feature - border radius. But what I want to discuss today is another cool solution that is actually cross browser one. The RoundedCorners control that is available in the ASP.NET AJAX toolkit.

Let's say we have a simple div control:

   <div id="test" style="background-color:Red;width:200px;height:200px;">

        aaa

   </div>


That looks like this:

image

and we want to make it rounded. Here is the server RoundedCorner control definition to achieve this:

 <cc1:RoundedCornersExtender ID="RoundedCornersExtender1" runat="server"

         TargetControlID="test" Color="red"

         Radius="6" 

         Corners="All" />

(and naturally I added a script manager to the page and added the “Register” directive as well).

 

The result is this:

image

 

So how does the control work:

As it turns out, the control does not use any images , it does it using a very nice technique. If you look at the source code that is created for our div ( using any tool, I used the IE 8 developer tool bar) you will see the following code:


<DIV style="BACKGROUND-COLOR: red; HEIGHT: 1px; MARGIN-LEFT: 3px; FONT-SIZE: 1px; OVERFLOW: hidden; MARGIN-RIGHT: 3px" __roundedDiv="true"></DIV>
<DIV style="BACKGROUND-COLOR: red; HEIGHT: 1px; MARGIN-LEFT: 2px; FONT-SIZE: 1px; OVERFLOW: hidden; MARGIN-RIGHT: 2px" __roundedDiv="true"></DIV>
<DIV style="BACKGROUND-COLOR: red; HEIGHT: 1px; MARGIN-LEFT: 1px; FONT-SIZE: 1px; OVERFLOW: hidden; MARGIN-RIGHT: 1px" __roundedDiv="true"></DIV>
<DIV style="BACKGROUND-COLOR: red; HEIGHT: 1px; MARGIN-LEFT: 0px; FONT-SIZE: 1px; OVERFLOW: hidden; MARGIN-RIGHT: 0px" __roundedDiv="true"></DIV>
<DIV style="BACKGROUND-COLOR: red; HEIGHT: 1px; MARGIN-LEFT: 0px; FONT-SIZE: 1px; OVERFLOW: hidden; MARGIN-RIGHT: 0px" __roundedDiv="true"></DIV>


<DIV style="BORDER-BOTTOM: medium none; BORDER-LEFT: medium none; BACKGROUND-COLOR: red; WIDTH: 100%; HEIGHT: 200px; BORDER-TOP: medium none; BORDER-RIGHT: medium none">aaa </DIV>


<DIV style="BACKGROUND-COLOR: red; HEIGHT: 1px; MARGIN-LEFT: 0px; FONT-SIZE: 1px; OVERFLOW: hidden; MARGIN-RIGHT: 0px" __roundedDiv="true"></DIV>
<DIV style="BACKGROUND-COLOR: red; HEIGHT: 1px; MARGIN-LEFT: 0px; FONT-SIZE: 1px; OVERFLOW: hidden; MARGIN-RIGHT: 0px" __roundedDiv="true"></DIV>
<DIV style="BACKGROUND-COLOR: red; HEIGHT: 1px; MARGIN-LEFT: 1px; FONT-SIZE: 1px; OVERFLOW: hidden; MARGIN-RIGHT: 1px" __roundedDiv="true"></DIV>
<DIV style="BACKGROUND-COLOR: red; HEIGHT: 1px; MARGIN-LEFT: 2px; FONT-SIZE: 1px; OVERFLOW: hidden; MARGIN-RIGHT: 2px" __roundedDiv="true"></DIV>
<DIV style="BACKGROUND-COLOR: red; HEIGHT: 1px; MARGIN-LEFT: 3px; FONT-SIZE: 1px; OVERFLOW: hidden; MARGIN-RIGHT: 3px" __roundedDiv="true"></DIV>
<DIV style="BACKGROUND-COLOR: red; HEIGHT: 1px; MARGIN-LEFT: 6px; FONT-SIZE: 1px; OVERFLOW: hidden; MARGIN-RIGHT: 6px" __roundedDiv="true"></DIV></DIV>

All the control is doing is simply adding some div controls above it and under it. (The above divs are for the top corners and the bottom divs are for the bottom corners) And all that is changing between all these divs is the margin-left and margin-right property. which means each div is a simple 1 px height control that follows by another div that is longer and so on….

Amazing and simple right?

The problem with this control is that i does not support 2 colors, which means that if you have a div that it’s upper side is in one color and the bottom side is in another color, you simply have to do it manually.

ASP:Chart control – Amazing

Today I discovered something I should have known long ago. ASP.NET has a Chart control!!! It is free to download and use and it will be part of ASP.NET 4.0 coming up soon.

If you wish to use it today simply follow these steps:

1. Download and install the  Chart controls.

2. Download and install the VS 2008 tool support.

3. Optional: Download the code samples. This is a huge web application project we can learn a lot from.

Here are some snap shots of what you can do with these control I took from the sample web project:

ChartImg2 ChartImg3 ChartImg4 3DSpline ChartImg5 2DDoughnut2 2DPolar ChartImg6 ChartImg

Enjoy.

Building ASP.NET Real – time web application – Part 5

After seeing the core of the real-time solution in post 1 – 4 this post will show the other code parts and specify a few details and steps we can take to optimize the solution:

So here are the missing codes to complete the puzzle:

The StocksValuesDB class, that simulate a DB being updated in each interval and has an event to tell clients when an update occurs:

public class StocksValuesDB

{

     //The event this DB raised when the data changes

     public delegate void StocksChangedDeleaget(StocksEventArgs args);

     public static event StocksChangedDeleaget OnStocksChanged;

     public static bool Initialized { get; private set; }

     public static int Stock1Value { get; set; }

     public static int Stock2Value { get; set; }

     public static int Stock3Value { get; set; }

     public static int Stock4Value { get; set; }

     public static int Stock5Value { get; set; }

    private static Timer oStocksTimer;

    static StocksValuesDB()

    {

          Initialized = true;

         //Start a timer that simulate a change to the stocks

         oStocksTimer = new Timer();

         oStocksTimer.Interval = 2000;

         oStocksTimer.Elapsed += new ElapsedEventHandler(StocksTimer_Elapsed);

         oStocksTimer.Enabled = true;

         oStocksTimer.Start();

    }

 

    private static void StocksTimer_Elapsed(object sender, ElapsedEventArgs e)

    {

        //Stop the timer and uppdate the stocks

         oStocksTimer.Stop();

  

         Random oRandom = new Random();

         Stock1Value = oRandom.Next(1,1000);

         Stock2Value = oRandom.Next(1, 1000);

         Stock3Value = oRandom.Next(1, 1000);

         Stock4Value = oRandom.Next(1, 1000);

         Stock5Value = oRandom.Next(1, 1000);

         oStocksTimer.Start();

         if(OnStocksChanged != null)

         {

            OnStocksChanged(new StocksEventArgs(Stock1Value, Stock2Value, Stock3Value,

                                           Stock4Value, Stock5Value));

          }

   }

}

The StocksEventArgs class, to be used as the event args for the OnStocksChanged event.

  public class StocksEventArgs : EventArgs

  {

      public StocksValues Stocks;

      public StocksEventArgs(int nStock1Value, int nStock2Value, int nStock3Value, int

            nStock4Value, int nStock5Value)

      {

          Stocks = new StocksValues

                       {

                         Stock1Value = nStock1Value,

                         Stock2Value = nStock2Value,

                         Stock3Value = nStock3Value,

                         Stock4Value = nStock4Value,

                         Stock5Value = nStock5Value

                     };

            }

  }

The StocksValues class, to be passes as a memeber of the event args to the clients.

public class StocksValues

  {

        public int Stock1Value { get; set; }

        public int Stock2Value { get; set; }

        public int Stock3Value { get; set; }

        public int Stock4Value { get; set; }

        public int Stock5Value { get; set; }

  }

The AsyncCallbacksWrapper class, wrapp the AsyncResult object with extra data.

public class AsyncCallbacksWrapper

{

         #region Class members

         //For holding the AsyncResultm for the Async handler

         public AsyncResult<StocksValues> AsyncResult { get; set; }

         //For knowing if it's the same user

         public string SessionID { get; private set; }

         #endregion

 

        #region Class Constructors

        public AsyncCallbacksWrapper(string sSessionID)

        {

          this .SessionID = sSessionID;

        }

        #endregion

}

Te code that I downloaded from the internet and is used as a generic class that implement IAsyncResult can be found in the complete solution file here.

A few important notes:

1. Don’t be afraid if you are getting HTTP 403.9 error, all you need to do is to make sure to abort the timeout request and invoking the handler in case of timeouts or windows close event.If you are using IIS 5.1 you will get it a lot since it is limited to 10 connections.

2. Use TCPView tool to watch what happens on the server and on the client IE.

3. I used a timer to simulate the DB being updated, you can even use SQLCacheDependency

   with polling or notification services ( I tried it it worked).

4. Use the AsyncCallbacksWrapper to add more properties to be filtered later. Instead

   of waiting all the client in case of an updat , you can filter the clients that are

   interested in this event or even filder the Data being returned to them.

Enjoy.

 

Building ASP.NET Real – time web application – Part 4

In the previous post, I explained how to use the HTTP Async handler (or simply Async page) in order to create a callback and store it somewhere. Later when something changes this callback will be invoked and update the web client waiting for update. But what is this callback ,how do we get it invoked and what is BeinXXX and EndXXX in this post:

Asynchronous Programming Model:

When an application performs an IO operation, the application is very much depend on the device that is doing this IO work. for example when you are trying to read something from a FileStream or a NetworkStream, even worse , if this file you are trying to read is in a remote machine and this machine is offline , your application is waiting until timing out! You can assign a different thread to do this “dirty work” but when you will create many thread the application will suffer from this overhead (context switching and so on). So when you have IO operations like this and you will your application to be more scalable and reliable you should not do these operations Synchronous. You should use the APM. so how does it work?

An application wishing to support the APM, meaning to have a method that works Synchronously and Asynchronously will provide the method itself,  lets call it Func, a BeingFunc and an EndFunc methods. (Just like our HTTP handler has public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) and public void EndProcessRequest(IAsyncResult asyncResult))

Lets being with the BeinXXX method: this method will return an object implementing IAsyncResult (is implemented by classes containing methods that can operate asynchronously) The class implementing this interface stores state information for an asynchronous operation and provides a synchronization object to allow threads to be signaled when the operation completes. So basically this is the object that monitors the operations and update it’s state. Now for the parameters the BeginXXX accepts. It accepts AsyncCallback object which is a delegate pointing to a function to be invoked when this Async operation is ended! look at the signature of this delegate:

public delegate void AsyncCallback( IAsyncResult ar)

as you can see it gets as a parameter the IAsyncResult object that has the information and state about the Async operation. In additon, the BeginXXX method gets another parameter that is the state of the operation in order to distinguish the operations and to supply extra data.

So in our case (The HTTP handler) we are creating our own AsyncResult object ( that implement IAsync) , and store this object in the manager:

AsyncCallbacksWrapper oAsync = new AsyncCallbacksWrapper( this.sSessionID)

                              {

                               AsyncResult = new AsyncResult<StocksValues>(cb, null),  

                              };

StocksClientsManager.Instance.AddCallBack(oAsync);

and then returning it.as you can see the first parameter is the cb, which is the ASP.NET call back to be invoked when we want it to be.

When we decide to invoke this cb, all we need to do is to find it inside our IAsync object and invoke it ( so it will get to the EndXXX method of the HTTP handler).

More on the APM:

http://msdn.microsoft.com/en-us/library/system.iasyncresult.aspx

http://msdn.microsoft.com/en-us/library/system.asynccallback.aspx

http://msdn.microsoft.com/he-il/magazine/cc163467(en-us).aspx

All there is left is to show the other parts of the application, read more in the next post.

More Posts Next page »