Saturday, January 26, 2008

Using PreviousPage with a Master Page

Using the PreviousPage scenario, with Master Pages presents its own particular problems, but they're not hard to overcome. As you may have noticed, using "PreviousPage" scenario isn't quite as simple as it looks in all the tutorials. In fact, using most of the tutorials/code samples on the web, doesn't work at all. That's specifically because they aren't taking into consideration, that, with a Master Page, you have a ContentPlaceholder, and you must first look there, to find the data from the previous page.

For those who don't know, the base samples show a scenario in which the 'Submit' button on the first page has it's PostBackURL property assigned to the second page in the postback scenario. The code, then would look something like:

Dim Name As TextBox
Name = Page.PreviousPage.FindControl("txtName")
Label1.Text = Name.Text
As we stated earlier, if you're using a Master Page in your website (with a Master Page designated, specifically, in the submitting page), this doesn't work. In able to do this, you must look in the Content Placeholder of the submitting page, first. Therefore, the code would look more like this:
Dim ph As ContentPlaceHolder = CType(PreviousPage.Master.FindControl("YourContentPlaceholderID"), ContentPlaceHolder
Dim tb As TextBox = CType(ph.FindControl(YourControlID), TextBox)
Label1.Text = tb.Text
In this sample, we first look inside the submitting page, then we find the Contentplaceholder. Then, once we find the contentPlaceholder, we look inside it, to find the control, from which we need to retrieve the data. Here's a small function which does all this for us, to cut down on repetitive code:
Function GetData(ByVal CtrlID As String) As String
Dim ph As ContentPlaceHolder = CType(PreviousPage.Master.FindControl("YourContentPlaceholderID"), ContentPlaceHolder)
If Not ph Is Nothing Then
Dim tb As TextBox = CType(ph.FindControl(CtrlID), TextBox)
If Not tb Is Nothing Then
Return tb.Text
End If
End If
Return String.Empty
End Function
Then, to use it, you merely do something like this:
lblName.Text = GetData("txtName")
That's all there is to it. Have fun!

Monday, January 7, 2008

Managing State in ASP.NET

ne of ASP.NET's main improvements over classic ASP is its improved options for state management. Die-hard ASP classic developers moving to ASP.NET are often surprised by the dramatic change in programming paradigm. The powerful state management techniques in ASP.NET make Web development much more like traditional Windows desktop programming. This article shows you how to use the various techniques for managing state in ASP.NET and the pitfalls of each method.


Managing State the ASP.NET Way
The simple application shown in Figure 1 illustrates how ASP.NET manages state:


Figure 1: The application retains the text in the label between postbacks to the server.
The dropdown list and the button shown in Figure 1 are part of an HTML form. When the user clicks the Submit button, the browser posts the form back to the server. Forms in ASP.NET (aspx) pages post back to the originating page by default. The server-side code takes the item the user selected and uses it to create the text of a Label control on the Web page that shows the item selected. ASP.NET's automatic state management preserves the text in the Label control between postbacks as well as the user's selection in the Listbox. You don't have to write any extra code to make the items retain state between postbacks.

In contrast, using classic ASP, even a simple application such as this requires several lines of additional codes to ensure that the Listbox item remains selected and to preserve the text in the Label control. You have to write the additional code because HTTP is a stateless protocol. The Web server treats each request as a new connection; the server "forgets" about all requests immediately after processing them. In other words, in classic ASP, unless you write the state management code yourself, after each postback the user's Listbox selection will be lost (reset to the first item).

In ASP.NET, the list box is a Web server control. Web server controls can automatically maintain their state and you can manipulate them on the server programmatically. That change has far-reaching ramifications for how you should think about state management in ASP.NET. To have a better understanding of how ASP.NET manages the state for you, take a look at the source for the page shown in Figure 1.

   



The preceding code shows a part of the HTML generated by ASP.NET. The HTML contains a hidden field called Viewstate that holds a string of characters. That string stores the state of the various controls on a Web Form. When the server processes a Web Form, it hashes and stores the state of the controls in that form in the Viewstate hidden field before it sends the page to the browser for display. When the browser posts the form back to the server, ASP.NET reads the values stored in Viewstate to restore the state of the controls. It is important to understand that Viewstate maintains information that would not normally be posted back to the server. For example, in the sample application, the HTML form would automatically post the item selected by the user back to the server, but would not post back the text in the Label control. So there's no point in Viewstate storing the item selected, because it can restore the selected item from the information posted by the form. Hence Viewstate stores the text in the Label control but not the item selected.

You can examine what the form sends to the server by using the GET method instead of the POST method. Simply change the method property of the form from post to get. Now when the form is submitted, you can examine the URL to see the form data sent back to the server:

   
http://localhost/StateManagement/WebForm1.aspx?
__VIEWSTATE=dDwxNTgwOTQ2NjA3Ozs%2B&lstLanguages=
VB.NET&cmdSubmit=Submit

Click on the Submit button a few times and note how the length of the Viewstate parameter value increases!

State Management in an ASP .Net

State Management in an ASP .Net application.


When users visit Web sites it becomes necessary to maintain session related and controls related information. In an HTTP exchange between a browser and a remote host, session related information which identifies state, such as a unique session ID, information about the user's preferences or authorisation level is preserved. Note that sessions are maintained in the data being exchanged.

State Management is the process by which we maintain session related information and additional information about the controls and its state. The necessity of state management arises when multiple users request for the same or different Web Pages of a Web Site.

State management can be accomplished using Client Side options or the Server side options.

Client Side State Management Options

Client Side State Management involves storing information either on a Web page or on a Client computer. There are four ways to manage states.

  • View State
  • Hidden Form Fields
  • Cookies
  • Query String

View State

In this method, the ViewState property that is inherited from the base Control class is used to automatically save the values of the page and of each control prior to rendering of the page. ViewState is implemented with a hidden form field called the _VIEWSTATE, which is automatically created in every Web Form page. When ASP.Net executes a Web page on a Web Server, the values stored in the ViewState property of the page and controls on it are collected and formatted into a single encoded string. The encoded string is then assigned to the Value attribute of the hidden form field _VIEWSTATE and is sent to the client as a part of the Web page.

Hidden Form Fields

In ASP.Net we can use the HTML standard hidden fields in a Web Form to store page-specific information. A hidden field does not render in a Web browser. However, we can set the properties of the hidden field. When a page is submitted to the server, the content of the hidden field is sent in the HTTP Form collection along with values of other controls.

Cookies

A cookie is a small data structure used by a Web server to deliver data to a web client. A cookie contains page specific information that a Web server sends to a client along with Page output. Cookies are used to keep track of each individual user who accesses the web page across a HTTP connection.

Query String

The Query string is a part of the request that appears after the Question mark (?) character in the URL. A query string provides a simple way to pass information from one page to another.

Server Side State Management Options

Application State

ASP.Net provides application state as a means of storing global application specific information. The information in the application state is stored in a key value pair and is used to maintain data consistency between server round trips and between pages.

Session State

In this option session state used to store session specific information for a Web site. In session state, the scope fo session state is limited to the current browser session. In case, many users are accessing the same Web application, each will have a different session state. If a user exits from a Web applicatin and returns later, it will be a different session state.

Database Support

Another option is the database support option. Database support is used in combination with cookies or session state. The database used is usually a relational database.

Multi-threading in .NET

Multi-threading in .NET: Introduction and suggestions

One of the greatest understatements I've heard in a newsgroup was made by Patricia Shanahan, in a Java newsgroup in 2001: "Multi-threaded programming needs a little care." Multi-threading is probably one of the worst understood aspects of programming, and these days almost all application programmers need to understand it to some extent. This article acts as an introduction to multi-threading and gives some hints and tips for how to do it safely. Warning: I'm not an expert on the subject, and when the real experts start discussing it in detail, my head starts to spin somewhat. However, I've tried to pay attention to those who know what they're doing, and hopefully the contents of this article form at least part of a multi-threading "best practice".

This article uses the C# type shorthands throughout - int for Int32 etc. I hope this makes it easier for C# developers to read, and won't impede any other developers too much. It also only talks about the C# ways of declaring variables to be volatile and locking monitors. Developers using other languages can find the equivalents in their own preferred environment, I'm sure.

Introduction: What is multi-threading?

The fact that you're reading this article in the first place means you probably have at least some idea of what multi-threading is about: it's basically trying to do more than one thing at a time within a process.

So, what is a thread? A thread (or "thread of execution") is a sort of context in which code is running. Any one thread follows program flow for wherever it is in the code, in the obvious way. Before multi-threading, effectively there was always one thread running for each process in an operating system (and in many systems, there was only one process running anyway). If you think of processes running in parallel in an operating system (e.g. a browser downloading a file and a word processor allowing you to type, both "at the same time"), then apply the same kind of thinking within a single process, that's a reasonable way to visualise threading.

Multi-threading can occur in a "real" sense, in that a multi-processor box may have more than one processor executing instructions for a particular process at a time, or it may be effectively "simulated" by multiple threads executing in sequence: first some code for thread 1 is executed, then some code for thread 2, then back to thread 1 etc. In this situation, if both thread 1 and thread 2 are "compute bound" (all they're doing is computation, without waiting for any input from the network, or file system, or user etc) then that won't actually speed things up at all - in fact, it'll slow things down as the operating system has to switch between threads, and the memory cache probably won't be as effective. However, much of today's computing involves waiting for something to happen, and during that time the processor can be doing something else. Intel's "Hyper-Threading" technology which is on some of its more recent chips (bearing in mind that this article was written in early 2004!) is a sort of hybrid between this "real" and "simulated" threading - for more information, see Intel's web page on the subject.

How does multi-threading work in .NET?

.NET has been designed from the start to support multi-threaded operation. There are two main ways of multi-threading which .NET encourages: starting your own threads with ThreadStart delegates, and using the ThreadPool class either directly (using ThreadPool.QueueUserWorkItem) or indirectly using asynchronous methods (such as Stream.BeginRead, or calling BeginInvoke on any delegate).

In general, you should create a new thread "manually" for long-running tasks, and use the thread pool only for brief jobs. The thread pool can only run so many jobs at once, and some framework classes use it internally, so you don't want to block it with a lot of tasks which need to block for other things. The examples in this article mostly use manual thread creation. On the other hand, for short-running tasks, particularly those created often, the thread pool is an excellent choice.

Multi-threaded "Hello, world"

Here is virtually the simplest threading example which actually shows something happening:

using System;
using System.Threading;

public class Test
{
static void Main()
{
ThreadStart job = new ThreadStart(ThreadJob);
Thread thread = new Thread(job);
thread.Start();

for (int i=0; i < 5; i++)
{
Console.WriteLine ("Main thread: {0}", i);
Thread.Sleep(1000);
}
}

static void ThreadJob()
{
for (int i=0; i < 10; i++)
{
Console.WriteLine ("Other thread: {0}", i);
Thread.Sleep(500);
}
}
}

The code creates a new thread which runs the ThreadJob method, and starts it. That thread counts from 0 to 9 fairly fast (about twice a second) while the main thread counts from 0 to 4 fairly slowly (about once a second). The way they count at different speeds is by each of them including a call to Thread.Sleep, which just makes the current thread sleep (do nothing) for the specified period of time. Between each count in the main thread we sleep for 1000ms, and between each count in the other thread we sleep for 500ms. Here are the results from one test run on my machine:

Main thread: 0
Other thread: 0
Other thread: 1
Main thread: 1
Other thread: 2
Other thread: 3
Main thread: 2
Other thread: 4
Other thread: 5
Main thread: 3
Other thread: 6
Other thread: 7
Main thread: 4
Other thread: 8
Other thread: 9

One important thing to note here is that although the above is very regular, that's by chance. There's nothing to stop the first "Other thread" line coming first, or the pattern being slightly off - Thread.Sleep is always going to be somewhat approximate, and there's no guarantee that the sleeping thread will immediately start running as soon as the sleep finishes. (It will become able to run, but another thread may be currently running, and on a single processor machine that means the thread which has just "woken up" will have to wait until the thread scheduler decides to give it some processor time before it next does anything.)

As with all delegates, there's nothing to restrict you to static methods, or methods within the class that the delegate is used from. You need to have access to the method, of course, and if you want to specify an instance method, you have to use a particular instance. Here's another version of the program above, using an instance method in a different class. If the Count method had been static, the value of the job variable would have been new ThreadStart(Counter.Count). Most examples given in this article use methods within the same class, but that's just for brevity and simplicity.

using System;
using System.Threading;

public class Test
{
static void Main()
{
Counter foo = new Counter();
ThreadStart job = new ThreadStart(foo.Count);
Thread thread = new Thread(job);
thread.Start();

for (int i=0; i < 5; i++)
{
Console.WriteLine ("Main thread: {0}", i);
Thread.Sleep(1000);
}
}
}

public class Counter
{
public void Count()
{
for (int i=0; i < 10; i++)
{
Console.WriteLine ("Other thread: {0}", i);
Thread.Sleep(500);
}
}
}

Friday, January 4, 2008

Callback Code in .NET

___________________________________________________________________________



private string _callbackResult = null ;

protected void page_Load( object sender , EventArgs e)

{

string cbreference = Page.ClientScript.GetCallbackEventReference(this,"arg" , " GetRandomNumberFormServer", "context");

string cbscript = "function UseCallback(arg , context ) " + "{"+ cbReference +"}";

Page.ClientScript.RegisterClietScriptBlock(this.GetType(), "UseCallback" , cbScript , true );
}


public void RaiseCallbackEvent(string eventArg)
{

Random rnd = new Random();
_callbackResult = rnd.Next().ToString();
}

public
{

return _callbackResult;

}