Thursday, March 31, 2011

Resolving Deadlocks in SQL Server 2000

Resolving Deadlocks in SQL Server 2000
Your application can detect a deadlock and resubmit its transaction, but a better approach is to resolve a deadlock by changing the conditions that lead to it in the first place. In this article, you'll learn how SQL Server deadlocks arise, what types of deadlocks there are, and how you can resolve them.
When your application must handle complex transactions and multiple users, SQL Server deadlocking can be an annoying and difficult problem.
Deadlocking is not a problem that is unique to SQL Server. Any database system that relies on locking to ensure that user transactions do not interfere with each other is subject to deadlock conditions. In order to understand and resolve SQL Server deadlocks, it's important to understand the basic concepts underlying deadlocking in SQL Server.
Deadlocking Concepts
The key concept behind deadlocking is the transaction. To give your users a consistent view of the database, where either all changes in a transactional unit of work succeed or all fail, the database system must lock some resources while the work is being done. A SQL Server deadlock occurs when two or more processes have acquired locks on their respective resource, and they need to get an incompatible lock on the other's resource in order to finish a transaction. The result is mutual blocking: each waits on each other to acquire some resource that the other process already has.
"
A SQL Server deadlock occurs when two or more processes have acquired locks on their respective resource, and they need to get an incompatible lock on the other's resource in order to finish a transaction. The result is mutual blocking: each waits on the other to acquire some resource that the other process already has.
"
The result is a situation where neither process can finish. SQL Server's lock manager will detect a deadlock cycle and end one of the transactions. Table 1 shows how, in general, a deadlock occurs.
Read the table from top to bottom, imagining time to progress from instance T1 through T7. By time T3, Transaction1 and Transaction2 have both been granted locks on some resource. At time T4, Transaction1 requests an incompatible lock on the resource already locked by Transaction2, and is blocked. At that point, Transaction1 goes into a wait state, waiting for the lock to be released.
At time T5, Transaction2 requests an incompatible lock on the resource that Transaction1 already has locked. At this point, Transaction2 also goes into a wait state, and each process is blocking the other. This is a deadlock cycle, and here is where SQL Server will detect the deadlock cycle and end one of the transactions.
Types of waits
According to SQL Server Books Online, SQL Server threads can wait on
  • Locks
  • Parallel query resources
  • Other threads
  • Memory resource
  • Application events
Deadlocking can occur with locks, parallelism, threads, and application events. (Memory waits are resolved by query time-out.) The most frequent source of SQL Server deadlocking is resource locking where the resources are table or index objects.
Deadlocks Involving Locks
Lock-based deadlocks involve two or more threads, at least one transaction, and one or more resources. It's useful to view deadlocks as occurring in two stages. The first is a grant stage, where each thread is granted a lock on its resource. They could be the same resource, but it's much more common that they are different resources.
The second stage is a blocked request where each thread requests an incompatible lock on the other thread's resource. Each thread waits on the other to release its locks before it can complete. SQL Server detects the deadlocked state and rolls back one of the transactions.
"
Deadlocking is more than blocking. Blocking occurs when one thread is waiting on another, and some brief blocking is normal.
"
Deadlocking is more than blocking. Blocking occurs when one thread is waiting on another, and some brief blocking is normal. Blocking is expected in any database system that uses locking to maintain transaction isolation. Only blocks with long durations should be considered a problem. In an active system, short periods of blocking may be happening quite often. Lock-based deadlocking is a special type of blocking where two or more threads mutually block each other, and that's what you need to avoid.
How SQL Server handles a Deadlock
In SQL Server 2000, the Lock Monitor thread detects the deadlock. It uses a periodic detection system, inspecting processes about every 5 seconds to determine if there are any deadlock cycles. When it finds one, it automatically chooses one thread as the deadlock victim. It then rolls back the victim thread's transaction, cancels its query, and returns error 1205 to its client.
The Lock Monitor generally chooses the least expensive transaction to roll back. You can override this somewhat using SET DEADLOCK_PRIORITY to LOW for a session. But whenever both threads have the same DEADLOCK_PRIORITY setting, the Lock Monitor will have to choose one of them as the victim.
The message delivered by error 1205 is mysterious or entertaining, depending on your point of view:
Server: Msg 1205, Level 13, State 50, Line 1Transaction (Process ID 54) was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
Error 1205 is not fatal to the connection; your connection is not terminated. SQL Server aborts the batch, rolls back the transaction, and cancels the query. As a result, error 1205 cannot be detected from within Transact-SQL by @@ERROR within the batch or from calling a stored procedure, because the entire calling batch is cancelled. It has a severity level of 13, correctable by the user, so the client can resubmit the query.
Unfortunately, error 1205 does not tell you the identity of the other participating spid or spids that your process deadlocked with. It also does not reveal statements at the grant or blocked request stage, so you are not sure what commands set up the deadlock conditions in the first place. 


Common Table Expressions (CTE) on SQL 2005 By Don Schlichting

Introduction

New in SQL 2005 are Common Table Expressions, CTE for short. A Common Table Expression is an expression that returns a temporary result set from inside a statement. This result set is similar to a hybrid Derived Table meets declared Temporary Table. The CTE contains elements similar to both. Some of the most frequent uses of a Common Table Expression include creating tables on the fly inside a nested select, and doing recursive queries. Common Table Expressions can be used for both selects and DML statements. The natural question is, if we have been using TSQL for this long without Common Table Expressions, why start using them now? There are several benefits to learning CTEs. Although new to SQL Server, Common Table Expressions are part of ANSI SQL 99, or SQL3. Therefore, if ANSI is important to you, this is a step closer. Best of all, Common Table Expressions provide a powerful way of doing recursive and nested queries in a syntax that is usually easier to code and review than other methods.

CTE

Below is very simple Common Table Expression example. All the CTE examples in this article were created on SQL 2005 Beta 2 Developer Edition. The example CTE will be used to return the list price of products, and our sell price, which is five percent below list. This first example is very simple, and could be replaced by a single select statement, but it will demonstrate some key CTE points. The examples will get more advanced as the article progresses.
USE AdventureWorks
GO

WITH MyCTE( ListPrice, SellPrice) AS
(
  SELECT ListPrice, ListPrice * .95
  FROM Production.Product
)

SELECT *
FROM MyCTE

GO
The database, Adventure Works, is now the SQL 2005 default sample database. Gone are the days of Northwind. On the beta version used for this article, Adventure Works did not install by default. Instead, during install, click Advanced then select sample databases.
The Common Table Expression is created using the WITH statement followed by the CTE name. Immediately trailing is a column list, in our case, we are returning two columns, ListPrice, and SellPrice. After the AS, the statement used to populate the two returning columns begins. The CTE is then followed by a select calling it.
The BOL format of a Common Table Expression is listed below;
[ WITH <common_table_expression> [ ,...n ] ]

<common_table_expression>::=
    expression_name [ ( column_name [ ,...n ] ) ]
    AS
    ( CTE_query_definition )

Temporary Tables

This small example displays several interesting concepts. The CTE is called by name from the SELECT * statement, similar to a Temporary Table. However, if a Temporary Table were used, it would first have to be created, and then populated;
CREATE TABLE #MyCTE
(
  ListPrice money,
  SellPrice money
)

INSERT INTO #MyCTE
 (ListPrice, SellPrice)
 SELECT ListPrice, ListPrice * .95
 FROM Production.Product   
However, a Temporary Table could be called over and over again from with in a statement. A Common Table Expression must be called immediately after stating it. Therefore, in this example, the call to the CTE will fail.
USE AdventureWorks
GO

WITH MyCTE( ListPrice, SellPrice) AS
(
  SELECT ListPrice, ListPrice * .95
  FROM Production.Product
)

SELECT *
FROM Production.Location

SELECT *
FROM MyCTE

GO
The call to MyCTE will fail with the following error:
Msg 208, Level 16, State 1, Line 14
Invalid object name 'MyCTE'.
The CTE itself has some syntactical restrictions. Compute, Order By (without a TOP), INTO, Option, FOR XML, and FOR BROWSE are all not allowed.


http://www.databasejournal.com/features/mssql/article.php/3502676/Common-Table-Expressions-CTE-on-SQL-2005.htm

Tuesday, March 29, 2011

ASP.NET AJAX Control Toolkit

Welcome to the ASP.NET AJAX Control Toolkit.

Choose from any of the samples on the left to see the live controls in action, and experiment with their different possibilities.
What is the ASP.NET AJAX Control Toolkit?
The ASP.NET AJAX Control Toolkit is an open-source project built on top of the Microsoft ASP.NET AJAX framework. It is a joint effort between Microsoft and the ASP.NET AJAX community that provides a powerful infrastructure to write reusable, customizable and extensible ASP.NET AJAX extenders and controls, as well as a rich array of controls that can be used out of the box to create an interactive Web experience.

The AJAX Control Toolkit contains more than 30 controls that enable you to easily create rich, interactive web pages.

To get started, and to install the Ajax Control Toolkit, visit the AJAX Control Toolkit Project Page on CodePlex.

To learn more, read the Getting Started Tutorial, or the other walkthroughs, tutorials and videos shown on the left

Cloud Spend Analytics using CloudRows


AWS Spending Analytics

Review and analyze your IT expenses

CloudRows delivers an extensive set of AWS activity and spending reports, in a unified, easy-to-use analytical dashboard.
Key reports:
* Spending overview and drilldown
* Activity overview and drilldown
* Budget tracking status

http://www.cloudrows.com/

MVC Advantages and disadvantages

Languages of the real and artificial.

Web MVC

The Model-View-Controller (MVC) architecture is a standard architecture for interactive applications. In client-server programming, the MVC components are distributed across at least two nodes of a network. This leads to a set of choices about where to deploy each component of the architecture. One solution is the traditional server-based MVC model. Another is the Rich Internet Application (RIA) model. In a real-world application with client-side validation, these are more similar than they might seem.

Desktop MVC

In an interactive application, there is typically a domain model, code to present the model to the user, and code to act upon the model in response to the user manipulation of input devices such as the keyboard and mouse. For example, in a word processor the domain model is the document, which contains entities such as paragraphs, spans, and styles. The system presents the document to the user as (for a sighted user) glyphs rendered as pixel patterns, and interprets keystrokes and mouse actions as edit, formatting, and control commands.
Smalltalk-80 introduced the Model-View-Controller (MVC) architecture for structuring this type of application. MVC separates the maintainance of the domain model (the Model), the presentation of the model (the View), and the interpretation of user input (the Controller).
Model-View-Controller Control Flow2

Wednesday, March 23, 2011

Reading and Writing Files in SQL Server using T-SQL

SQL Server has never been short of ways to read from and write to files and it is always better to use the standard techniques provided by SQL Server where possible. However, most of them are really designed for reading and writing tabular data and aren't always trouble-free when used with large strings or relatively unstructured data.
For reading tabular data from a file, whether character-delimited or binary, there is nothing that replaces the hoary old Bulk Copy Program (BCP), which underlies more esoteric methods such as Bulk Insert. It is possible to read text-based delimited files with ODBC, simple files can be read and written-to using xp_cmdshell, and you will find that OSQL is wonderful for writing results to file, but occasionally I've found I need to do more than this.
Thankfully, when armed with OLE Automation and the FileSystem Object (FSO), all sorts of things are possible. The FileSystem Object was introduced into Windows to provide a single common file-system COM interface for scripting languages. It provides a number of handy services that can be accessed from TSQL. In this article, I provide examples of stored procedures that use this interface to allow you to:
  • Read lines of text from a file
  • Read a file into a SQL Server data type
  • Write out to a file
  • Get file details
  • Tidy up XML, XHTML or HTML code
I'll provide a few details on the FSO along the way, but let's start with examples of some of these procedures in action. You'll need to enable OLE Automation on your test server in order to follow along.

Reading lines from a file

I have often pined for a simple function that will read information a line at a time, and to present to me a 'fake table' where each line of text is a row, with a primary key based on the line number. With such a function, one can then do one's own parsing and checking of data.
Well, here it is. Create the uftReadFileAsTable stored procedure in your test database, and try it out with something like:
 
Select line from
 Dbo.uftReadfileAsTable('MyPath','MyFileName')
where line not like '#%'
--where line doesnt begin with a hash
Just fill in an existing file name and path to the file you wish to read, instead of 'MyPath' and 'MyFileName', and away you go.
This is a method I use for reading web logs and gathering usage statistics. It is also useful where the data feed has to be validated before one can parse it into the final SQL data format.

Reading a file into a SQL Server data type

This is all very well, but how about something that reads a file in one gulp into a varchar or XML datatype? Perhaps you need to extract data from HTML, XHTML or some other format. Create the ufsReadfileAsString procedure and try something like…
Select dbo.ufsReadfileAsString ('MyPath','MyFileName')

Writing out a file

No problem – just create spWriteStringToFile and try:
execute spWriteStringToFile 'This article describes how to fully access the
local filesystem from SQL Server. It shows a
way of reading and writing data to file, and
accessing the details of the server's
filesystem using OLE Automation to access
the filesystem object'
, 'MyPath','MyFileName'
The path you use instead of 'MyPath' will have to exist, in this example.

Getting file details

If you need to find out the attributes of a particular file, then try out spFileDetails:

Maps in SQL Server 2008 R2 Reporting Services

Problem
I noticed a new feature in SQL Server 2008 R2 Reporting Services that allows you to render maps in your reports.  Can you provide some details on this new feature and can I take advantage of it even though don't have any spatial columns in my data warehouse?
Solution
SQL Server 2008 introduced new spatial data types including a geography type that can be used to stored latitude and longitude coordinates.  The new map feature in SQL Server Reporting Services 2008 R2 works with the geography type as well as with state abbreviations, state names, or state numbers.  The built-in map feature allows you to add a map to a report and show the states in the US or the counties within a state.  You can use the map to render one or more data points, providing a slick visualization of your data by state or county within a state.
In this tip I will walk through creating a report with a map.  As an example I will create a simple report using Business Intelligence Development Studio (BIDS).  A preview of the report is shown below:
My report will use the AdventureWorksDW2008R2 database and show reseller sales by state.  I will use the following query to retrieve the total reseller sales for a given calendar year by state:
SELECT g.StateProvinceCode, SUM(f.ExtendedAmount) Sales
FROM dbo.FactResellerSales f
JOIN dbo.DimDate d ON d.DateKey = f.ShipDateKey
JOIN dbo.DimReseller s ON s.ResellerKey = f.ResellerKey
JOIN dbo.DimGeography g ON g.GeographyKey = s.GeographyKey
WHERE d.CalendarYear = @CALENDAR_YEAR
AND g.CountryRegionCode = 'US'
GROUP BY g.StateProvinceCode
To add a map to a report, double click Map from the Toolbox as shown below:.


http://www.mssqltips.com/tip.asp?tip=2174

Thursday, March 17, 2011

Reading And Writing Isolated Storage In Silverlight

http://asimsajjad.blogspot.com/2010/11/reading-and-writing-isolated-storage-in.htmlIn this post I will show you how you can create file on the Isolated Storage and also write on that file and also how can you check the size of the Isolated storage.Isolated storage is a mechanism that allows you to preserve data across browser sessions on a user’s machine. This storage area is tied to an individual user and helps you overcome the 4 KB limitation of a cookie. Unlike a cookie, isolated storage lies outside of the browser cache.
The code which is used to write in the Isolated Storage is listed in List 1.The class used for the Isolated Storage is IsolatedStorageFile which represents an isolated storage area containing files and directories. IsolatedStorageFile class has static method with the name GetUserStoreForApplication which is used to obtains user-scoped isolated storage corresponding to the calling code's application identity. After retrieving the user isolated storage object next step is to create the stream object which is used to write the contains.

using (IsolatedStorageFile isolatedStoragFile = IsolatedStorageFile.GetUserStoreForApplication()) { using (IsolatedStorageFileStream stream = new IsolatedStorageFileStream("MyFileName.txt", FileMode.Append, isolatedStoragFile)) { using (StreamWriter writer = new StreamWriter(stream)) { writer.Write("Message Date And Time: " + DateTime.Now.ToString("dd/MM/yyyy HH:mm:ss") +" -> "+ txtTextToWrite.Text + "\r"); } stream.Close(); } }
List 1

IsolatedStorageFileStream is the class which Exposes a file within isolated storage.IsolatedStorageFileStream is used to read, write and create files in isolated storage. So if you want to read , write or create new file in the Isolated Storage area you need the object of the IsolatedStorageFileStream. I have passed the file name which in this case is .txt extension the, second parameter is the FileMode enumeration which has one of the values as listed in the table given below.The last parameter to the IsolatedStorageFileStream constructor is the IsolatedStorageFile object which is created before.

Browser Information In Silverlight

In this post I will show you how to get the browser information.To get the browser information the namespace used for this is System.Windows.Browser. The BrowserInformation object contains properties such as the name, product name, product version , browser version etc. Let us start with the example which will use to get this information and display on the screen which I will share with you at the end of the post I will use two screen shot one for the Internet explorer and the second one for the Fire Fox.
For this Example I have create one class with the name BrowserInfo  which has the properties like BrowserName , BrowerVersion, Platform, ProductName, UserAgent of type string , IsCookiesEnabled of type Boolean to indicate whether Cookies are enabled or not , BrowserMinorVersion and BrowserMajorVersion are of type int.You can see the default constructor of the BrowserInfo class which is used to initialize all the properties of the class.

public BrowserInfo() { BrowserName = HtmlPage.BrowserInformation.Name; BrowserVersion = HtmlPage.BrowserInformation.BrowserVersion.ToString(); BrowserMajorVersion = HtmlPage.BrowserInformation.BrowserVersion.Major; BrowserMinorVersion = HtmlPage.BrowserInformation.BrowserVersion.Minor; IsCookiesEnabled = HtmlPage.BrowserInformation.CookiesEnabled; Platform = HtmlPage.BrowserInformation.Platform; ProductName = HtmlPage.BrowserInformation.ProductName; ProductVersion = HtmlPage.BrowserInformation.ProductVersion; UserAgent = HtmlPage.BrowserInformation.UserAgent; }
List 1

In the code you can see that BrowserName property is assigned the value of the Name in the BrowserInformation object which is the static member of the HtmlPage static class which is reside in the System.Windows.Browser namespace. The Name property of the BrowserInformation return the version of the browser technology that the current browser is based on.The browser technology name is typically different from the browser product name. CookiesEnabled property of BrowserInformation object indicate whether the browser supports cookies or not. The ProductName property of the BrowserInformation object get the product name of the browser.The browser product name is the familiar name of the browser, such as "FireFox".
You can see the output of the two different browser One for the internet explorer and second one is by using the Fire fox you can see the different properties of the two browsers.

Fire Fox
Internet Explorer
You can also see the Major and Minor version of the browser as shown in the screen shots. The UserAgent property will Gets the user agent string of the browser.The Platform property will return name of the operating system that the browser is running on. You can use these properties to developer application like the Google analysis or you can use them to show the trend of your site the user operation system the browser name etc

http://asimsajjad.blogspot.com/2010/11/browser-information-in-silverlight.html

Ingredients for Perfect Web App Recipe , Silverlight 4.0 + WCF RIA Service+ Entity Framework

When Silverlight launched in 2006 , world saw it merely as a flash replacement but with Silverlight 4 things have changed a lot .Now Silverlight far ahead from its adobe competitor at least in terms of technology implementation and rich development environment .RIA enabled Business Apps with Silverlight is not just  a illogical stich of  technology concept but it is a well thought architectural paradigm shift ,In this post i am going to introduce RIA services in .Net framework 4.0 using Silverlight .
What is Silverlight
Needs no introduction , still if you are new then refer this wiki article What is Silverlight.
What is Entity Framework
Well a brief introduction has been published in my earlier posts , Refer ADO.Net Entity Framework
What Is WCF RIA Service
RIA applications give user rich desktop type like UX with client side browser plugin such as Silverlight.It differs from traditional web applications which mostly relies on stateless HTTP Requests to do operations where as RIA employs a State full client and async operation with servers on client demand.
Silverlight 4.0,WCF RIA Service, Entity Framework
Silverlight 4.0,WCF RIA Service, Entity Framework
In RIA ,the  app logic exposed to the client side needs to access the data and perform CRUD operation .Exposing all the operation code in client side will never be a good idea ,then how will it access ????By the way here WCF Services for RIA comes into picture.Then how RIA solves the problem ,let look into the diagram bellow it is quite self explanatory

Silverlight 4.0,WCF RIA Service, Entity FrameworkSilverlight 4.0,WCF RIA Service, Entity FrameworkSilverlight 4.0,WCF RIA Service, Entity FrameworkSilverlight 4.0,WCF RIA Service, Entity Framework http://manaspatnaik.com/blog/index.php/technology/silverlight-4/ingredients-for-perfect-web-app-recipe-silverlight-4-0-wcf-ria-service-entity-framework/373 ,

silverlight Tutorial, How to Learn Silverlight

Microsoft introduced the .NET Framework in 2000 as a new approach to software development. The .NET Framework borrowed ideas from the best practices in the software industry as well as brought new ideas to the table in an effort to meet developer needs and requests.
Virtually all programming languages manage data at some point. The primary reason that communication between applications created using C++, Visual Basic, Visual FoxPro, and other languages was difficult was because each language stored data being managed in a unique set of data types. For example, an integer in one language may not represent an integer in another language. Data needed to be converted to common data types to communicate between languages.
The .NET Framework introduced a common set of data types (the Common Type System) that is used by all .NET-compliant languages (C++, Visual Basic, C#, etc). Thus all languages can easily intercommunicate. Furthermore, all .NET-compliant languages render a common result when compiling code, Microsoft Intermediate Language (MSIL). (see footnote) MSIL can be deployed to any platform running the Common Language Runtime (CLR). Currently, the CLR is only available for Microsoft Windows although an open source version of the CLR was created for Linux (called the Mono Project). Code written by using the .NET Framework is compiled instead of interpreted resulting in much better performance than Java and competing technologies.
Microsoft took the Web development industry by storm with their .NET upgrade to ASP. ASP.NET put a new face on Web development through a compiled code architecture and improved state management and it provides access to the full functionality of the .NET Framework. ASP.NET is built around XML, supports the latest Web development standards, and allows for the creation of advanced Web Services.
The .NET Framework also provides improved data access and database integration through ADO.NET. For more information, see MSDN.
There are many more features and benefits of the .NET Framework than those mentioned here. The .NET Framework has become the leading software development environment available.

Introducing Silverlight

What's New in the .NET Framework

As of the writing of this course, version 3.5 of the .NET Framework has been released. Version 3.5 includes features that encompass all facets of Windows, Web, and network development:
  • Includes just under 10,000 classes, methods, and properties.
  • Complies with the latest Web development standards.
  • Introduces revolutionary technologies used in Windows Vista development, rich media and user experiences, workflow management, security and authorization, and complete distributed communication protocols.
The .NET Framework can also be fully extended by developers to create custom classes and types. The functionality of the .NET Framework spans the server, the workstation, and the Web. The four primary additions to the .NET Framework as of version 3.0 are:
  1. Windows Presentation Foundation (WPF)
  2. Windows Communication Foundation (WCF)
  3. Windows Workflow Foundation (WF)
  4. CardSpace

Windows Presentation Foundation (WPF)

WPF is used to develop elaborate user interfaces like those that adorn Windows Vista and managed advanced media streaming and integration. WPF is the a complete revamp of Windows Forms so that user interface, graphic, and media development is now designed around the .NET Framework.

Windows Communication Foundation (WCF)

WCF encompasses the ASP.NET Web Services and .NET remoting functionality that was contained in the .NET Framework 2.0 as well as new communication technologies.

Windows Workflow Foundation (WF)

WF is used to model complex workflow processes.

CardSpace

CardSpace is the embodiment of new security and user authorization functionality.

ASP.NET AJAX

ASP.NET AJAX was developed to improve performance in the browser by making post backs and calls between the browser and server asynchronously. ASP.NET AJAX uses new built-in types and controls and JavaScript.
Both ASP.NET and ASP.NET AJAX are heavily dependent upon the ASP.NET page event life cycle, are tightly coupled to the server, and have a tough time competing with advanced, media-rich plug-in solutions such as Adobe Flash. Additionally, it is difficult to create Web applications that offer a consistent experience across all supported browsers and platforms by using ASP.NET and AJAX. In 2006, Microsoft began developing a solution to extend into the browser and offer media experiences more robust than competing plug-in solutions.
In 2007, Microsoft introduced Silverlight. (see footnote) Silverlight is a free plug-in that encompasses a subset of functionality from the .NET Framework and WPF. In a manner similar to the JVM (see footnote), Silverlight runs in the browser as a "sandbox" - a secure zone installed into the browser that accommodates Silverlight functionality while completely protecting the host platform from any possibly adverse actions performed by Silverlight.

Silverlight Architecture

Unlike ASP.NET, the bulk of Silverlight processing occurs on the client machine thus decreasing server resource utilization and improving the Web experience on the client. The figure below shows the difference between ASP.NET processing and Silverlight processing:
When a client initially attempts to run a Silverlight application, if the Silverlight plug-in has not been installed on the client machine, it will be downloaded and installed. Upon subsequent requests to run the application, the application will instantiate on the client machine and make requests for resources from the server only when necessary. The Silverlight plug-in can be thought of as a scaled-down version of the full .NET Framework. It only contains those classes and functionality that are applicable to a Silverlight Web client and those were streamlined and optimized for use on the Web client machine.
Silverlight was designed using the same design paradigm as ASP.NET. Each page of a Silverlight application includes an associated code behind file that includes the code that handles events fired by the page. Silverlight resembles WPF in that it uses Extensible Application Markup Language (XAML) to construct the user interface (presentation layer). As Silverlight applications are composed of text-based files that include markup and code, they can be created using any text editor; however, more advanced tools and development environments such as Visual Studio or Expression Blend simplify the task significantly.


Splash Screen in Silverlight 4

In this post I will show you how to create the custom splash screen for your Silverlight application. You have seen many software which use nice splash screen during loading of the software applications like Microsoft office, excel and many others. I have also created splash screen for my desktop applications which I have developed during my professional life. But I didn’t created any for the web application which I have developed in asp.net. But now the Silverlight provide the functionality of the splash screen. Splash screens provide something interesting and creative to increase anticipation and excitement for the application.
The splash screen is displayed while the .xap file is downloading when the .xap file is downloaded the splash screen disappear. So xaml file for the splash screen is not included in the Silverlight application rather the splash screen file which is of xaml is placed in the web application. When Silverlight application start the default splash screen which you can see is the shown in the image 1. Here you can see the spinning blue balls animation splash screen.

Image 1

Let us start with the our own splash screen , the splash screen which I have created is shown in the Image 2. In Image 2 you can see that I have created simple splash screen for my application which will show the percentage complete in digits so that user can see how much the application is downloaded.
Image 2

The code for the splash screen which is written in the file SilverlightLoader.xaml is place in the web project which you can see after downloading the source code. The code consist of the grid layout and then Border and the textblock which will shown the download complete in percentage. I have also set drop shadow effect for the border which contain the text block control.
The next step is to integrate the custom splash screen with the web application. You can see in the List 1 splashScreenSource property is used to reference the splash screen. By using this property, you can point to where a custom splash screen’s XAML is stored.

<div id="silverlightControlHost"> <object id="SilverlightPlugIn" data="data:application/x-silverlight-2," type="application/x-silverlight-2" width="100%" height="100%"> <param name="source" value="ClientBin/Custom Splash Screen.xap" /> <param name="onError" value="onSilverlightError" /> <param name="background" value="white" /> <param name="minRuntimeVersion" value="4.0.50401.0" /> <param name="splashScreenSource" value="SilverlightLoader.xaml" /> <param name="onSourceDownloadProgressChanged" value="appDownloadProgressChanged" /> <param name="autoUpgrade" value="true" /> <a href="http://go.microsoft.com/fwlink/?LinkID=149156&v=4.0.50401.0" style="text-decoration: none"> <img src="http://go.microsoft.com/fwlink/?LinkId=161376" alt="Get Microsoft Silverlight" style="border-style: none" /> </a> </object> <iframe id="_sl_historyFrame" style="visibility: hidden; height: 0px; width: 0px; border: 0px"></iframe> </div>
List 1

The next step is to monitor the download progress of the .xap file for this you  need to wire up JavaScript event handlers to the onSourceDownload-ProgressChanged events defined by the plug-in. The definition of the changed event is listed in the List 2 as shown below. The onSourceDownloadProgressChanged event will fire any time the progress of a download has changed by 0.5 percent or more. If this event is triggered, you may access the total progress through the second parameter of the onSourceDownloadProgressChanged event. This parameter exposes a floating-point property called progress. The value of  this property is between 0.0 and 1.0, so you must multiply the value by 100 in order to convert the value to a percentage. When the progress has reached 1.0, the onSource- DownloadComplete event will fire.
 
 

Wednesday, March 16, 2011

Use Check Box In Gridview In Asp.net C#

In Aspx .Page Take Grid view Like Below

<head runat="server">
    <title>Grid CheckBox</title>
  
    <script type="text/javascript">
        function SelectAll(id)
        {
            //get reference of GridView control
            var grid = document.getElementById("<%= GridView1.ClientID %>");
            //variable to contain the cell of the grid
            var cell;
           
            if (grid.rows.length > 0)
            {
                //loop starts from 1. rows[0] points to the header.
                for (i=1; i<grid.rows.length; i++)
                {
                    //get the reference of first column
                    cell = grid.rows[i].cells[0];
                   
                    //loop according to the number of childNodes in the cell
                    for (j=0; j<cell.childNodes.length; j++)
                    {          
                        //if childNode type is CheckBox                
                        if (cell.childNodes[j].type =="checkbox")
                        {
                        //assign the status of the Select All checkbox to the cell checkbox within the grid
                            cell.childNodes[j].checked = document.getElementById(id).checked;
                        }
                    }
                }
            }
        }
    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" OnRowDataBound="GridView1_RowDataBound">
            <Columns>
                <asp:TemplateField>
                    <AlternatingItemTemplate>
                        <asp:CheckBox ID="cbSelectAll" runat="server" />
                    </AlternatingItemTemplate>
                    <HeaderTemplate>
                        <asp:CheckBox ID="cbSelectAll" runat="server" Text="Select All" />
                    </HeaderTemplate>
                    <ItemTemplate>
                        <asp:CheckBox ID="cbSelectAll" runat="server" />
                    </ItemTemplate>
                </asp:TemplateField>
                <asp:BoundField DataField="ApplicationName" HeaderText="Application Name" />
                <asp:BoundField DataField="ServerName" HeaderText="Server Name" />
            </Columns>
        </asp:GridView>
   
    </div>
    </form>
</body>
In Aspx.Cs Page Use this Code

using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Data;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            //Binding GridView with the datasource
            this.GridView1.DataSource = FillDataTable();
            this.GridView1.DataBind();
        }
    }

    /// <summary>
    /// Method that will add few rows in a DataTable and returns a DataTable
    /// </summary>
    /// <returns>DataTable</returns>
    protected DataTable FillDataTable()
    {
        DataTable dt = new DataTable();
        dt.Columns.Add("ApplicationID");
        dt.Columns.Add("ApplicationName");
        dt.Columns.Add("ServerName");

        DataRow dr = dt.NewRow();
        dr[0] = "1";
        dr[1] = "Application 1";
        dr[2] = "Server 1";
        dt.Rows.Add(dr);

        DataRow dr1 = dt.NewRow();
        dr1[0] = "2";
        dr1[1] = "Application 2";
        dr1[2] = "Server 2";
        dt.Rows.Add(dr1);

        DataRow dr2 = dt.NewRow();
        dr2[0] = "3";
        dr2[1] = "Application 3";
        dr2[2] = "Server 3";
        dt.Rows.Add(dr2);

        DataRow dr3  = dt.NewRow();
        dr3[0] = "4";
        dr3[1] = "Application 4";
        dr3[2] = "Server 4";
        dt.Rows.Add(dr3);

        DataRow dr4 = dt.NewRow();
        dr4[0] = "5";
        dr4[1] = "Application 5";
        dr4[2] = "Server 5";
        dt.Rows.Add(dr4);

        DataRow dr5 = dt.NewRow();
        dr5[0] = "6";
        dr5[1] = "Application 6";
        dr5[2] = "Server 6";
        dt.Rows.Add(dr5);

        return dt;
    }
    protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.Header)
        {
            //Find the checkbox control in header and add an attribute
            ((CheckBox)e.Row.FindControl("cbSelectAll")).Attributes.Add("onclick", "javascript:SelectAll('" + ((CheckBox)e.Row.FindControl("cbSelectAll")).ClientID + "')");
        }
    }
}

Catcha in Asp.net C#

USe this Class To Generate Captcha  in Your Site

CaptchaControl.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.UI;
using System.ComponentModel;

namespace CaptchaControl
{
    public class CaptchaControl : System.Web.UI.WebControls.WebControl,
        IPostBackDataHandler, INamingContainer, IValidator

    {
        #region Public Properties

        [DefaultValue(50),
         Description("Specify the height of the captcha image"),
         Category("Appearance")]
        public int DrawHeight { get; set; }

        [DefaultValue(200),
         Description("Specify the width of the captcha image"),
         Category("Appearance")]
        public int DrawWidth { get; set; }

        [DefaultValue(50),
         Description("Number of characters to be printed"),
         Category("Appearance")]
        public int NumberOfChars { get; set; }

        [Description("States the validation state of the user. True if validated else false"),
         Category("Properties")]
        public bool IsValidated { get { return _isValidated; } }

        #endregion

        #region Private Variables
       
        private bool _isValidated = false;
        private CaptchaImage _captcha = new CaptchaImage();
        private string _previousGUID = string.Empty;
       
        #endregion

        #region WebControl Members

        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            writer.Write("<Div><Table>");
            writer.Write("<tr><td><img src=\"CaptchaImage.aspx?guid="+ _captcha.UniqueID + "\"></tr></td>");
            writer.Write("<tr><td><input name=\"" + this.UniqueID + "\" type=text></tr></td>");
            writer.Write("</Table></Div>");
        }

        protected override void OnInit(EventArgs e)
        {
            Page.RegisterRequiresControlState(this);
            base.OnInit(e);
        }

        protected override void OnPreRender(EventArgs e)
        {
            if (this.Visible)
            {
                GenerateCaptcha();
            }
            base.OnPreRender(e);
        }

        protected override void LoadControlState(object savedState)
        {
            if (savedState != null)
            {
                _previousGUID = savedState.ToString();
            }
        }

        protected override object SaveControlState()
        {
            return _captcha.UniqueID;
        }

        #endregion

        #region Captcha Members

        private void GenerateCaptcha()
        {
            _captcha.DrawHeight = this.DrawHeight;
            _captcha.DrawWidth = this.DrawWidth;
            _captcha.NumberOfChars = this.NumberOfChars;

            HttpRuntime.Cache.Add(_captcha.UniqueID, _captcha, null, DateTime.Now.AddSeconds(60),
                   TimeSpan.Zero, System.Web.Caching.CacheItemPriority.NotRemovable, null);
        }

        private CaptchaImage GetCaptchaFromCache(string guid)
        {
            return (CaptchaImage)HttpRuntime.Cache.Get(guid);
        }

        private void RemoveCaptchaFromCache(string guid)
        {
            HttpRuntime.Cache.Remove(guid);
        }

        private void ValidateCaptcha(string data)
        {
            CaptchaImage captcha = GetCaptchaFromCache(_previousGUID);
            _isValidated = (captcha.CaptchaCode == data.ToUpper());
            if (_isValidated)
            {
                this.ErrorMessage = "Invalid code entered";
            }

            RemoveCaptchaFromCache(_previousGUID);
        }

        #endregion

        #region IPostBackDataHandler Members

        public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
        {
            ValidateCaptcha(postCollection[this.UniqueID].ToString());
            return false;
        }

        public void RaisePostDataChangedEvent()
        {
           
        }

        #endregion

        #region IValidator Members

        public string ErrorMessage
        {
            get;
            set;
        }

        public bool IsValid
        {
            get
            {
                return _isValidated;
            }
            set
            {
            }
        }

        public void Validate()
        {
        }

        #endregion
    }
}

CaptchaImage.cs

using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System;
using System.Web;

namespace CaptchaControl
{
     class CaptchaImage
    {
        #region Public Properties

        /// <summary>
        /// Draw width of the image
        /// </summary>
        public int DrawWidth
        {
            get
            {
                return _drawWidth;
            }
            set
            {
                _drawWidth = value;
            }
        }
       
        /// <summary>
        /// Draw height of image
        /// </summary>
        public int DrawHeight
        {
            get
            {
                return _drawHeight;
            }
            set
            {
                _drawHeight = value;
            }
        }

        /// <summary>
        /// Number of the characters to be shown
        /// </summary>
        public int NumberOfChars
        {
            get
            {
                return _numberOfChars;
            }
            set
            {
                _numberOfChars = value;
            }
        }

        /// <summary>
        /// Unique Id for this captcha control
        /// </summary>
        public string UniqueID
        {
            get
            {
                return _uniqueID;
            }
            set
            {
                _uniqueID = value;
            }
        }

        /// <summary>
        /// Code to be printed on the image
        /// </summary>
        public string CaptchaCode
        {
            get
            {
                return _captchaCode;
            }
            set
            {
                _captchaCode = value;
            }
        }

        #endregion

        #region Public Methods

        public CaptchaImage()
        {
            string captchaID = GetUniqueID();
            _uniqueID = captchaID;
        }

        /// <summary>
        /// Gets the cached captcha.
        /// </summary>
        /// <param name="guid">The GUID.</param>
        /// <returns></returns>
        public static CaptchaImage GetCachedCaptcha(string guid)
        {
            if (String.IsNullOrEmpty(guid))
                return null;

            return (CaptchaImage)HttpRuntime.Cache.Get(guid);
        }

        /// <summary>
        /// Generate the captcha image
        /// </summary>
        /// <returns>Captcha Image</returns>
        public Bitmap GenerateCaptcha()
        {
            return GenerateImage();
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Generate the captcha output image
        /// </summary>
        /// <param name="captchaCode"></param>
        /// <returns></returns>
        private Bitmap GenerateImage()
        {
            string captchaCode = GetCaptchaCode();
            _captchaCode = captchaCode;

            Bitmap bmp = new Bitmap(_drawWidth, _drawHeight,
                PixelFormat.Format32bppArgb);

            Graphics g = Graphics.FromImage(bmp);
            g.SmoothingMode = SmoothingMode.AntiAlias;
            Rectangle rect = new Rectangle(0, 0, _drawWidth, _drawHeight);

            HatchBrush brush = new HatchBrush(
              HatchStyle.Weave,
              Color.LightGray,
              Color.White);
            g.FillRectangle(brush, rect);

            g.DrawString(captchaCode,
                new Font("Tahoma", 28.0f, FontStyle.Bold),
                Brushes.Black, new PointF(0, 0));


            AddNoise(g);

            return bmp;
        }

        private void AddNoise(Graphics g)
        {
            Random rand = new Random();

            for (int i = 1; i < 500; i++)
            {
                int posX = rand.Next(1, _drawWidth);
                int posY = rand.Next(1, _drawHeight);
                int width = rand.Next(3);
                int height = rand.Next(3);
                g.DrawEllipse(Pens.Black, posX , posY,
                    width, height);  
            }
        }

        /// <summary>
        /// Generate a unique id for the this control
        /// </summary>
        /// <returns></returns>
        private string GetUniqueID()
        {
            return Guid.NewGuid().ToString();
        }

        private string GetCaptchaCode()
        {
            Random rand = new Random();
            string code = "";
            int charLen = _charSet.Length;

            for (int i = 0; i < _numberOfChars; i++)
            {
                int pos = rand.Next(0,charLen);
                code += _charSet.Substring(pos, 1);
            }

            return code;
        }

        #endregion

        #region Private Fields

        /// <summary>
        /// Char set for generating Captcha Code
        /// </summary>
        private const string _charSet = "ACDEFGHJKLNPQRTUVXYZ234679";

        private int _drawWidth = 200;

        private int _drawHeight = 50;

        private int _numberOfChars = 6;

        private string _uniqueID;

        private string _captchaCode;

        #endregion
    }
}
 

Chat Application In Asp.net c#

Use this Global Class Application For Developing Chat Engine

using System;

using System.Threading ;

using System.Web;

using System.Collections;

using System.Collections.Specialized;

using System.Text;

namespace ASPNETChat

{

    /// <summary>

    /// The business logic of the chat application

    /// </summary>

    public class ChatEngine

    {

        private static Hashtable Rooms = new Hashtable(40);

        public ChatEngine()

        {

        }


        /// <summary>

        /// Deletes the empty chat rooms

        /// </summary>

        /// <param name="state"></param>

        public static void CleanChatRooms(object state)

        {

            Monitor.Enter(Rooms);

            foreach(object key in Rooms.Keys)

            {

                ChatRoom room=(ChatRoom)Rooms[key.ToString()];

                room.ExpireUsers(100);

                if (room.IsEmpty())

                {

                    room.Dispose();

                    Rooms.Remove(key.ToString());

                }

            }

            Monitor.Exit(Rooms);

        }

        /// <summary>

        /// Returns the chat room for this two users or create a new one if nothing exists

        /// </summary>

        /// <param name="user1ID"></param>

        /// <param name="user2ID"></param>

        /// <returns></returns>

        public static ChatRoom GetRoom(string user1ID,string user2ID)

        {

            return GetRoom(user1ID,"",user2ID,"");

        }

        /// <summary>

        /// Returns or creats a chat room for these two users or create a new one if nothing exists

        /// </summary>

        /// <param name="user1ID"></param>

        /// <param name="user1Name"></param>

        /// <param name="user2ID"></param>

        /// <param name="user2Name"></param>

        /// <returns></returns>

        private static ChatRoom GetRoom(string user1ID,string user1Name,string user2ID,string user2Name)

        {

            ChatRoom room=null;

            string rid1=CreateRoomID(user1ID,user2ID);

            string rid2=CreateRoomID(user2ID,user1ID);

            Monitor.Enter(Rooms);


            if (Rooms.Contains(rid1))

                room=(ChatRoom)Rooms[rid1];

            else

            {

                if (Rooms.Contains(rid2))

                    room=(ChatRoom)Rooms[rid2];

                else

                {

                    //if (user1Name=="" && user2Name=="")

                    // return null;

                    //else

                    room=new ChatRoom(user1ID,user1Name,user2ID,user2Name);

                    Rooms.Add(rid1,room);

                }


            }

            Monitor.Exit(Rooms);

            return room;

        }


        #region Room ID,User IDs Manipulation

        /// <summary>

        /// Creates the room id using the ids of the two users

        /// </summary>

        /// <param name="user1"></param>

        /// <param name="user2"></param>

        /// <returns></returns>

        public static string CreateRoomID(string user1,string user2)

        {


            user1=user1.ToUpper();

            user2=user2.ToUpper();

            return user1+";"+user2;

        }

        #endregion

        #region Delete Room

        /// <summary>

        /// Deletes the specified room

        /// </summary>

        /// <param name="roomID"></param>

        public static void DeleteRoom(string roomID)

        {

            Monitor.Enter(Rooms);

            ChatRoom room=(ChatRoom)Rooms[roomID];

            room.Dispose();

            Rooms.Remove(roomID);

            Monitor.Exit(Rooms);

        }

        public static void DeleteRoom(string user1id,string user2id)

        {

            DeleteRoom(CreateRoomID(user1id,user2id));

        }

        #endregion

    }




    public class ChatRoom : IDisposable

    {

        //public Hashtable activeUsers = null;

        public ArrayList messages = null;

        public string RoomID;

        private ChatUser FirstUser;

        private ChatUser SecondUser;

        public void Dispose()

        {


            this.messages.Clear();

            this.RoomID="";

            this.FirstUser.Dispose();

            this.SecondUser.Dispose();

        }

        /// <summary>

        /// Returns the user with the specified id

        /// </summary>

        /// <param name="userID"></param>

        /// <returns></returns>

        public ChatUser GetUser(string userID)

        {

            userID=userID.ToUpper();

            if (FirstUser.UserID.ToUpper()==userID)

                return FirstUser;

            else

                return SecondUser;

        }


        #region constructors

        public ChatRoom(string user1ID,string user1Name,string user2ID,string user2Name)

        {

            this.messages = new ArrayList();

            this.RoomID=ChatEngine.CreateRoomID(user1ID,user2ID);

            this.FirstUser=new ChatUser(user1ID,user1Name);

            this.SecondUser=new ChatUser(user2ID,user2Name);

        }

        #endregion


        /// <summary>

        /// Determines if the users of the room are active or not

        /// </summary>

        /// <returns></returns>

        public bool IsEmpty()

        {

            lock(this)

            {

                if (this.FirstUser.IsActive==false&& this.SecondUser.IsActive==false)

                    return true;

                else

                    return false;

            }

        }



        #region Operations Join,Send,Leave

        //

        /// <summary>

        /// Marks the user as inactive

        /// </summary>

        /// <param name="userID"></param>

        /// <returns></returns>

        public string LeaveRoom(string userID)

        {

            //deactivate user

            ChatUser user=this.GetUser(userID);

            user.IsActive=false;

            user.LastSeen=DateTime.Now;


            //Add leaving message

            Message msg = new Message(user.UserName ,"",MsgType.Left);

            this.AddMsg(msg);

            //Get all the messages to the user

            int lastMsgID;

            ArrayList previousMsgs= this.GetMessagesSince( user.LastMessageReceived,out lastMsgID);

            user.LastMessageReceived=lastMsgID;

            //return the messages to the user

            string str=GenerateMessagesString(previousMsgs);

            if (IsEmpty())

                ChatEngine.DeleteRoom(this.RoomID);

            return "";

        }

        /// <summary>

        /// Activates the user and adds a join message to the room

        /// </summary>

        /// <param name="userID"></param>

        /// <param name="userName"></param>

        /// <returns>All the messages sent in the room</returns>

        public string JoinRoom(string userID,string userName)

        {

            //activate user

            ChatUser user=this.GetUser(userID);

            user.IsActive=true;

            user.UserName=userName;

            user.LastSeen=DateTime.Now;

            //Add join message

            Message msg=new Message(user.UserName ,"",MsgType.Join);

            this.AddMsg(msg);


            //Get all the messages to the user

            int lastMsgID;

            ArrayList previousMessages=this.GetMessagesSince(-1,out lastMsgID);

            user.LastMessageReceived=lastMsgID;


            //return the messages to the user

            string str=GenerateMessagesString(previousMessages);

            return str;

        }

        /// <summary>

        /// Adds a message in the room

        /// </summary>

        /// <param name="strMsg"></param>

        /// <param name="senderID"></param>

        /// <param name="toUserID"></param>

        /// <returns>All the messages sent from the other user from the last time the user sent a message</returns>

        public string SendMessage(string strMsg,string senderID,string toUserID)

        {

            ChatUser user=this.GetUser(senderID);

            Message msg=new Message(user.UserName ,strMsg,MsgType.Msg);

            user.LastSeen=DateTime.Now;

            this.ExpireUsers(100);

            this.AddMsg(msg);

            int lastMsgID;

            ArrayList previousMsgs= this.GetMessagesSince( user.LastMessageReceived,out lastMsgID);

            if (lastMsgID!=-1)

                user.LastMessageReceived=lastMsgID;

            string res=this.GenerateMessagesString(previousMsgs);

            return res;

        }

        #endregion

        /// <summary>

        /// Removes the users that hasn't sent any message during the last window secondes

        /// </summary>

        /// <param name="window">time in secondes</param>

        public void ExpireUsers(int window)

        {

            lock(this)

            {

                if (this.FirstUser.LastSeen != System.DateTime.MinValue )

                {

                    TimeSpan span = DateTime.Now - this.FirstUser.LastSeen;

                    if (span.TotalSeconds > window && this.FirstUser.IsActive!=false)

                    {

                        this.LeaveRoom(this.FirstUser.UserID);

                    }

                }

                if (this.SecondUser.LastSeen != System.DateTime.MinValue )

                {


                    TimeSpan span = DateTime.Now - this.SecondUser.LastSeen;

                    if (span.TotalSeconds > window && this.SecondUser.IsActive!=false)

                    {

                        this.LeaveRoom(this.SecondUser.UserID);

                    }

                }

            }

        }

        /// <summary>

        /// Adds a message to the room

        /// <param name="msg"></param>

        /// <returns> the id of the new message</returns>

        public int AddMsg(Message msg)

        {

            int count;

            lock(messages)

            {

                count = messages.Count;

                messages.Add(msg);

            }

            return count;

        }

        /// <summary>

        /// Iterates over the messages array calling ToString() for each message

        /// </summary>

        /// <param name="msgs"></param>

        /// <returns></returns>

        private string GenerateMessagesString(ArrayList msgs)

        {

            string res="";

            for (int i=0;i<msgs.Count;i++)

            {

                res+=((Message)msgs[i]).ToString()+"\n";

            }

            return res;

        }

        /// <summary>

        /// Returns an array that contains all messages sent after the message with id=msgid

        /// </summary>

        /// <param name="msgid">The id of the message after which all the message will be retuned </param>

        /// <param name="lastMsgID">the id of the last message returned</param>

        /// <returns></returns>

        public ArrayList GetMessagesSince(int msgid,out int lastMsgID)

        {

            lock(messages)

            {

                if ((messages.Count) <= (msgid+1))

                    lastMsgID=-1;

                else

                    lastMsgID=messages.Count-1;

                return messages.GetRange(msgid+1 , messages.Count - (msgid+1));

            }

        }


        /// <summary>

        /// Returns all the messages sent since the last message the user received

        /// </summary>

        /// <param name="userID"></param>

        /// <returns></returns>

        public string UpdateUser(string userID)

        {

            ChatUser user=this.GetUser(userID);

            user.LastSeen=DateTime.Now;

            this.ExpireUsers(100);

            int lastMsgID;

            ArrayList previousMsgs= this.GetMessagesSince( user.LastMessageReceived,out lastMsgID);

            if (lastMsgID!=-1)

                user.LastMessageReceived=lastMsgID;

            string res=this.GenerateMessagesString(previousMsgs);

            return res;

        }

    }

    #region the ChatUser Class

    public class ChatUser : IDisposable

    {

        public string UserID;

        public string UserName;

        public bool IsActive;

        public DateTime LastSeen;

        public int LastMessageReceived;

        public ChatUser(string id,string userName)

        {

            this.UserID=id;

            this.IsActive=false;

            this.LastSeen=DateTime.MinValue ;

            this.UserName=userName;

            this.LastMessageReceived=0;

        }

        public void Dispose()

        {

            this.UserID="";

            this.IsActive=false;

            this.LastSeen=DateTime.MinValue ;

            this.UserName="";

            this.LastMessageReceived=0;

        }

    }

    #endregion

    #region the Message Class

    public class Message

    {

        public string user;

        public string msg;

        public MsgType type;


        public Message(string _user, string _msg, MsgType _type)

        {

            user = _user;

            msg = _msg;

            type = _type;

        }

        public override string ToString()

        {

            switch(this.type)

            {

                case MsgType.Msg:

                    return this.user+" says: "+this.msg;

                case MsgType.Join :

                    return this.user + " has joined the room";

                case MsgType.Left :

                    return this.user + " has left the room";

            }

            return "";

        }


        public Message(string _user, MsgType _type) : this(_user, "", _type) { }

        public Message(MsgType _type) : this("", "", _type) { }

    }

    public enum MsgType { Msg, Start, Join, Left, Action }

    #endregion

}