Thursday, December 6, 2012

HTTP Handlers


HTTP Handlers 


      An ASP.NET HTTP handler is the process (frequently referred to as the "endpoint") that runs in response to a request made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page through the page handler. You can create your own HTTP handlers that render custom output to the browser.

Typical uses for custom HTTP handlers include the following:

  • RSS feeds   To create an RSS feed for a Web site, you can create a handler that emits RSS-formatted XML. You can then bind a file name extension such as .rss to the custom handler. When users send a request to your site that ends in .rss, ASP.NET calls your handler to process the request.

  • Image server   If you want a Web application to serve images in a variety of sizes, you can write a custom handler to resize images and then send them to the user as the handler's response.
HTTP handler and module features include the following:
  • The IHttpHandler and IHttpModule interfaces are the starting point for developing handlers and modules.
  • The IHttpAsyncHandler interface is the starting point for developing asynchronous handlers.
  • Custom handler and module source code can be put in the App_Code folder of an application, or it can be compiled and put in the Bin folder of an application.
  • Handlers and modules developed for use in IIS 6.0 can be used in IIS 7.0 with little or no change. For more information, see Moving an ASP.NET Application from IIS 6.0 to IIS 7.0.
  • Modules can subscribe to a variety of request-pipeline notifications. Modules can receive notification of events of the HttpApplication object.
  • In IIS 7.0, the request pipeline is integrated with the Web server request pipeline. HTTP modules can be used for any request to the Web server, not just ASP.NET requests.

HTTP Handlers

An ASP.NET HTTP handler is the process that runs in response to a request that is made to an ASP.NET Web application. The most common handler is an ASP.NET page handler that processes .aspx files. When users request an .aspx file, the request is processed by the page handler.
The ASP.NET page handler is only one type of handler. ASP.NET includes several other built-in handlers such as the Web service handler for .asmx files.

Built-in HTTP Handlers in ASP.NET

ASP.NET maps HTTP requests to HTTP handlers based on a file name extension. Each HTTP handler can process individual HTTP URLs or groups of URL extensions in an application. ASP.NET includes several built-in HTTP handlers, as listed in the following table.
HandlerDescription
ASP.NET page handler (*.aspx)
The default HTTP handler for all ASP.NET pages.
Web service handler (*.asmx)
The default HTTP handler for Web service pages
created as .asmx files in ASP.NET.
Generic Web handler (*.ashx)
The default HTTP handler for all Web handlers that do not have a 
UI and that include the @ WebHandler directive.
Trace handler (trace.axd)
A handler that displays current page trace information.

Creating a Custom HTTP Handler

To create a custom HTTP handler, you create a class that implements the IHttpHandler interface to create a synchronous handler. Alternatively, you can implementIHttpAsyncHandler to create an asynchronous handler. Both handler interfaces require that you implement the IsReusable property and the ProcessRequest method. TheIsReusable property specifies whether the IHttpHandlerFactory object (the object that actually calls the appropriate handler) can put the handler in a pool and reuse it to increase performance. If the handler cannot be pooled, the factory must create a new instance of the handler every time that the handler is needed.
The ProcessRequest method is responsible for processing individual HTTP requests. In this method, you write the code that produces the output for the handler.
HTTP handlers have access to the application context. This includes the requesting user's identity (if known), application state, and session information. When an HTTP handler is requested, ASP.NET calls the ProcessRequest method of the appropriate handler. The code that you write in the handler's ProcessRequest method creates a response, which is sent back to the requesting browser.

Mapping a File Name Extension

When you create a class file as your HTTP handler, the handler can respond to any file name extension that is not already mapped in IIS and in ASP.NET. For example, if you are creating an HTTP handler for generating an RSS feed, you can map your handler to the .rss file name extension. In order for ASP.NET to know which handler to use for your custom file name extension, in IIS you must map the extension to ASP.NET. Then in the application, you must map the extension to the custom handler.
By default, ASP.NET maps the file name extension .ashx to an HTTP handler. If you add the @ WebHandler directive to a class file, ASP.NET automatically maps the .ashx file name extension to the default HTTP handler. This is similar to the way ASP.NET maps the .aspx file name extension to the ASP.NET page handler when the @ Page directive is used. Therefore, if you create an HTTP handler class that has the file name extension .ashx, the handler is automatically registered with IIS and ASP.NET.
If you want to create a custom file name extension for a handler, you must explicitly register the extension with IIS and ASP.NET. The advantage of not using the .ashx file name extension is that the handler is then reusable for different extension mappings. For example, in one application the custom handler might respond to requests that end in .rss. In another application, it might respond to requests that end in .feed. As another example, the handler might be mapped to both file name extensions in the same application, but might create different responses based on the extension.
The process for registering a handler's custom file name extension is different in IIS 7.0 and in earlier versions of IIS. 

Asynchronous and Synchronous HTTP Handlers

An HTTP handler can be either synchronous or asynchronous. A synchronous handler does not return until it finishes processing the HTTP request for which it is called. An asynchronous handler runs a process independently of sending a response to the user. Asynchronous handlers are useful when you must start an application process that might be lengthy and the user does not have to wait until it finishes before receiving a response from the server.

Asynchronous HTTP handlers enable you to start an external process, such as a method call to a remote server. The handler can then continue processing without waiting for the external process to finish. While an asynchronous HTTP handler is processing, ASP.NET puts the thread that would ordinarily be used for the external process back into the thread pool until the handler receives a callback from the external process. This can prevent thread blocking and can improve performance because only a limited number of threads can execute at the same time. If many users request synchronous HTTP handlers that rely on external processes, the operating system can run out of threads, because many threads are blocked and are waiting for an external process.

When you create an asynchronous handler, you must implement the IHttpAsyncHandler interface. You must also implement the BeginProcessRequest method in order to initiate an asynchronous call that processes individual HTTP requests. In addition, you must implement the EndProcessRequest method to run cleanup code when the process ends.

Custom IHttpHandlerFactory Classes

The IHttpHandlerFactory class receives requests and is responsible for forwarding a request to the appropriate HTTP handler. You can create a custom HTTP handler factory by creating a class that implements the IHttpHandlerFactory interface. A custom handler factory can give you finer control over how HTTP requests are processed by creating different handlers based on run-time conditions. For example, with a custom HTTP handler factory, you can instantiate one HTTP handler for a file type if the HTTP request method is PUT, and another if the method is GET.

cont....

Friday, October 19, 2012

Agile Development Checklist


Introduction

The purpose of this article is to define a set of ideal practices for an agile software development project. The idea for this article came to me after discussing CMMI-type processes and realizing that there is no agile equivalent. I encourage you to leave comments about this article using the discussions module at the bottom of this page. Please note that the practices listed are the practices that I believe are essential to a good agile development project; they do not necessarily have anything to do with being agile. I have tried to list the practices in descending order of importance.

Practice 1: Aggressive refactoring

In my opinion, refactoring is the most overlooked skill for a software developer. A well refactored application has a much higher value to the project sponsor than a poorly refactored application. The most common sign of code in need of refactoring is excessively long methods. I try to keep methods to less than 100 lines. Other common code smells are misleading or meaningless variable names, and code duplication. Static code analysis tools, such as FxCop, can provide a useful measure of code quality.

Practice 2: Testing

Firstly, there should be some developer testing. All the code that is written should be testable and should have tests written for it. It is acceptable to modify your program to facilitate good testing. I believe that the traditional testing terms; unit tests, integration tests and system tests have become outdated. Instead, I prefer the terms developer tests, functional tests and non-functional tests. Non-functional tests are things like performance testing, functional tests are tests that the customer cares about like use case tests or business transaction tests, and developer tests are everything else that the developer needs to test to prove to herself that the code is correct.
We should automate as much testing as possible and run it as part of continuous integration. If code coverage analysis is included in the automated testing it provides a nice indication of the health of the system at any point of time.

Practice 3: Automated build and deployment

The project should have an automated build, an automated deployment and ideally automated testing. In the optimal situation, a developer can click a button and the build process will build the latest source, deploy, test and report on the result. Automating these processes not only saves time but also eliminates a huge number of bugs and time wasters.

Practice 4: Continuous integration

If a project has automated build, deployment and testing then continuous integration is really just a matter of automating the kick-off of that build, deploy test cycle. Every checkin should result in a new build and test, on a separate build server. The results of this should be reported to every team member and it should be an established team practice to immediately fix the build. A working build should be everyone's top priority. People should not be made to feel bad if they break the build, as this decreases their courage.

Practice 5: Source control

A source control system should be used to store all project artifacts including: code, non-code documentation, build scripts, database schema and data scripts, and tests. The code should not be checked into the build until it compiles and passes its tests.

Practice 6: Communication plan

There should be a defined, direct communication channel between the developers and the customers. This can be (best to worst): on demand face-to-face communication, daily or weekly face-face communication, contact phone numbers, instant messaging, email mailing list, intermediary (BA or PM). These communication channels can and should be combined.

Practice 7: Task tracking

There should be a defined technique for recording and prioritizing development tasks and bugs. The system should make it possible to assign responsibility for tasks to individuals. If tasks are tracked against estimates then the estimate should be performed by the person who will do the task.

Practice 8: Self documenting code

Code comments should be subjected to the same quality requirements as the code itself. Everything possible should be done to ensure that no other technical documentation is required. When non-code technical documentation is required it should be subject to the following restrictions: referenced from the code, always up-to-date (change when the code changes), only one version per baseline, stored in source control.

Practice 9: Peer review

There must be some form of peer review, such as code review of fellow programmers. If the developers are subjected to performance reviews then the peer reviews they do should be an input to that process. This helps to avoid the temptation to approve everything to avoid confrontation. Make sure that the reviews are for quality, not just for correctness.

Practice 10: Work-in-progress

A working version of the latest iteration should always be available for customer feedback. The advantage of this is that customers see very quickly when something has been developed contrary to what they had in mind. Shortening this feedback loop decreases the cost of change.

Practice 11: Feedback mechanism

There should be a defined mechanism for project team members, including the customer, to provide feedback on the project's processes. My suggestion is to hold a short meeting at the end of each iteration.

Wednesday, July 4, 2012

Like Operator in Linq


Sql Like Operator in Linq    


var query = from c in ctx.Customers
            where c.City == "London"
            select c;

The query that will be sent to the database will be:
SELECT CustomerID, CompanyName, ...
FROM    dbo.Customers
WHERE  City = [London]

we can write the query in different ways based on our requirement 

1. Using String.StartsWith or String.Endswith

Writing the following query:
var query = from c in ctx.Customers
            where c.City.StartsWith("Lo")
            select c;
will generate this SQL statement:
SELECT CustomerID, CompanyName, ...
FROM    dbo.Customers
WHERE  City LIKE [Lo%]which is exactly what we wanted. Same goes with String.EndsWith.
But, what is we want to query the customer with city name like "L_n%"? (starts with a Capital 'L', than some character, than 'n' and than the rest of the name). Using the query
var query = from c in ctx.Customers
            where c.City.StartsWith("L") && c.City.Contains("n")
            select c;
generates the statement:
SELECT CustomerID, CompanyName, ...
FROM    dbo.Customers
WHERE  City LIKE [L%]
AND      City LIKE [%n%]which is not exactly what we wanted, and a little more complicated as well.

2. Using SqlMethods.Like method

Digging into System.Data.Linq.SqlClient namespace, I found a little helper class called SqlMethods, which can be very usefull in such scenarios. SqlMethods has a method called Like, that can be used in a Linq to SQL query:
var query = from c in ctx.Customers
            where SqlMethods.Like(c.City, "L_n%")
            select c;
This method gets the string expression to check (the customer's city in this example) and the patterns to test against which is provided in the same way you'd write a LIKE clause in SQL.
Using the above query generated the required SQL statement:
SELECT CustomerID, CompanyName, ...
FROM    dbo.Customers
WHERE  City LIKE [L_n%]

Enjoy!

Wednesday, May 30, 2012

Installing ADO.Net Entity Framework with Package Manger Console


Installing ADO.Net Entity Framework with Package Manger Console


         ADO.Net Entity Framework is an ORM framework for .Net platform. It is integrated with LINQ to allow C# software developer to work with database elements, such as tables, using more familiar C# objects. There are lots of articles talking about ADO.Net Entity Framework, and there are many options to implement ORM on .Net platform (such as NHibernate). As usual, I won't discuss too much here. I just post a small tip about install Entity Framework 4.3 to your project. Hopefully this will save you some time.

       When you try to use "Add Library Package Reference..." to install Entity Framework 4.3, you may encounter an error stating " This package (or one of its dependencies) contains an init.ps1 file and needs to be installed from the Package Manager Console." This is because Entity Framework 4.3 package requires license agreement. You has to install it from Package Manger Console.

       You go to menu "Tools"->"Library Package Manager"->" Package Manger Console" to launch Package Manger Console.

       To do a keyword search in PM, type:

              PM> get-package -filter EntityFramework -listavailable

       You will get a list of packages.

       To install EntityFramework, type:

              PM> install-package EntityFramework
          
          PM will install EntityFramework 4.3.0 assuming you accept the license agreement.

Friday, April 13, 2012

SQL SEVER: How to make an Entry in Event Viewer using SQL SERVER


Today I came across the situation where I need to following scenario.

I need to make entry in Event Viewer when there is an error in Stored Procedure.

I wondered to do this, but finally I come up with the solution. SQL is much powerful.

SQL provides us to make an entry in Event Viewer by two ways:
1. using XP_LogEvent

2. By Raiserror WITH LOG

Lets first see the way using XP_LogEvent:

Here I have created one SP which will raise an error “Divide by zero error encountered.” as I tried to do “10 / 0”.

CREATE PROCEDURE TestEventViewer
AS
BEGIN TRY
SELECT 10/0
END TRY
BEGIN CATCH
PRINT ERROR_Message()
DECLARE @msg VARCHAR(100)
SELECT @msg = ERROR_Message()

EXEC xp_logevent 60000, @msg, informational

END CATCH

Lets Execute this SP:

EXEC TestEventViewer

This will write entry in Event Viewer. Now open Event Viewer. You can find Event Viewer at Control Panel –> Administrative Tools –> Event Viewer.

You will get en entry of Error there.

171

So we can do this by Extended Stored Procedure: “xp_logevent”.

Let see the parameters of this Procedure.

First Parameter: “60000” is the Error Number

Second Parameter: “@msg” is the message to be displayed in Event Viewer.

Third Parameter: “informational” is the Error Level. It could be “informational”, “Error”, “Warning”.

Now, Lets see by another way By Raiserror WITH LOG:

It is the same way as we used Raiserror to Raise an Error.

CREATE PROCEDURE TestEventViewer
AS
BEGIN TRY
SELECT 10/0
END TRY
BEGIN CATCH
PRINT ERROR_Message()
DECLARE @msg VARCHAR(100)
SELECT @msg = ERROR_Message()

RAISERROR(@msg, 11, 1) WITH LOG

END CATCH

Lets Execute this SP:

EXEC TestEventViewer.

So By these ways we can make an entry to Event Viewer.

Let me know if it helps you in any way

Thursday, March 15, 2012

How To Stop a Thread in .NET

Threads are a popular way of getting on with multiple things at once. They are not the only way of doing this, but they are particuarly attractive if you are faced with an API that is resolutely synchronous.

A common question that emerges once you have kicked off some concurrent work is: how do I stop it? Here are two popular reasons for wanting to stop some work in progress:

  1. You need to shut down the program.
  2. The user cancelled the operation.

In the first case, it is often acceptable to drop everything mid flow and not bother shutting down cleanly, because the internal state of the program no longer matters, and the OS will release many resources held by our program when it exits. The only concern is if the program stores state persistently - it is important to make sure that any such state is consistent when our program exits. However, if we are relying on a database for such state, we can still often get away with abandoning things mid flow, particularly if we are using transactions - aborting a transaction rolls everything back to where it was before the transaction started, so this should be sufficient to return the system to a consistent state.

There are of course cases where dropping everything on the floor will not work. If the application stores its state on disk without the aid of a database, it will need to take steps to make sure that the on-disk representation is consistent before abandoning an operation. And in some cases, a program may have interactions in progress with external systems or services that require explicit cleanup beyond what will happen automatically. However, if you have designed your system to be robust in the face of a sudden failure (e.g. loss of power) then it should be acceptable simply to abandon work in progress rather than cleaning up neatly when shutting the program down. (Indeed there is a school of thought that says that if your program requires explicit shutdown, it is not sufficiently robust - for a truly robust program, sudden termination should always be a safe way to shut down. And given that, some say, you may as well make this your normal mode of shutdown - it's a very quick way of shutting down!)

User-initiated cancellation of a single operation is an entirely different matter however.

If the user chooses to cancel an operation for some reason - maybe it is taking too long - she will expect to be able to continue using the program afterwards. It is therefore not acceptable simply to drop everything on the floor, because the OS is not about to tidy up after us. Our program has to live with its internal state after the operation has been cancelled. It is therefore necessary for cancellation to be done in an orderly fashion, so that the program's state is still internally consistent once the operation is complete.

Bearing this in mind, consider the use of Thread.Abort. This is, unfortunately, a popular choice for cancelling work, because it usually manages to stop the target thread no matter what it was up to. This means you will often see its use recommended on mailing lists and news groups as a way of stopping work in progress, but it is really only appropriate if you are in the process of shutting down the program, because it makes it very hard to be sure what state the program will be in afterwards.

Asynchronous Exceptions

The problem with Thread.Abort is that it can interrupt the progress of the target thread at any point. It does so by raising an 'asynchronous' exception, an exception that could emerge at more or less any point in your program. (This has nothing to do with the .NET async pattern by the way - that's about doing work without hogging the thread that started the work.)

Most exceptions are synchronous, meaning that it is possible to determine the points in a program at which such an exception might be thrown. For example, when you call System.Int32.Parse you know that it will throw a FormatException if there is something wrong with the string you pass it. Most importantly you know that it won't wait until you've executed a few lines of code before saying "oh by the way, here's an exception." If the call to Int32.Parse returns normally, you know that you won't be seeing a FormatException.

With asynchronous exceptions on the other hand, you never know where they might emerge - they could be thrown at more or less any point in your program's execution. This makes them rather hard to deal with - how are you supposed to cope gracefully with exceptions if you have no idea where they will emerge?

This is a particularly big problem for finally blocks. If you're doing your exception handling properly, you'll most likely have far more finally(or using) blocks in your code than you have catch blocks. This is because in order to recover successfully from an error, your code will need to tidy up after itself. And since C# doesn't support C++-style scope-based destructor execution, finally blocks (and their close cousins, usingblocks) are the only sane way of ensuring that such tidying is performed reliably.

Consider this code:

using (FileStream fs = File.Open(myDataFile,     FileMode.Open, FileAccess.ReadWrite, FileShare.None)) {     ...do stuff with data file... } 

This using block is really shorthand for this:

FileStream fs = File.Open(myDataFile,      FileMode.Open, FileAccess.ReadWrite, FileShare.None); try {     ...do stuff with data file... } finally {     IDisposable disp = fs;     disp.Dispose(); } 

The compiler will generate that finally block for us. (We could write it out in full like this every time, we just don't usually bother, because the first example is much more succinct and easier to read.) The whole idea of the using statement here is that it guarantees to close the file regardless of whether we leave the using block normally, or by throwing an exception.

Asynchronous exceptions weaken this guarantee.

Suppose the code above will be working on the file for some time, and you've decided to do it on some worker thread. Now suppose the user has chosen to cancel the operation, and your UI thread calls Thread.Abort to stop the operation. Most of the time, this will actually work. However, there's one situation in which it goes horribly wrong.

Suppose the worker thread had very nearly finished when the user decided to abort the operation. What happens if the worker thread has just entered the compiler-generated finally block when the UI thread calls Thread.Abort? If the worker thread is now in the finally block, it isoutside of the try block. This means that if the ThreadAbortException gets raised at this point, the remainder of the finally block won't run to completion. And if the worker thread hadn't quite managed to call Dispose yet, or it had but the FileStream object hadn't quite managed to close the file yet, the file isn't going to get closed.

At best, the FileStream's finalizer will eventually run and close the file. But it's conceivable that the FileStream.Dispose method might set its internal state to indicate that the file has been closed before it really closes the handle. Most classes aren't written to behave predictably if you start injecting asynchronous exceptions onto the thread you're calling their methods on.

The bottom line is that if an asynchronous exception occurs at the wrong moment, the file will remain open, possibly until the process exits. Since the file was opened for exclusive access, this means further attempts to open the file will fail until the process exits. The user will learn to hate your program.

This kind of thing is what makes async exceptions evil. And since Thread.Abort works by raising an asynchronous exception, we can conclude that Thread.Abort is evil. Hence the title.

Non-Evil Cancellation

Since Thread.Abort is bad news, how should we cancel operations? I think that if you're looking at how to do something to the worker thread to stop it, you're looking at it from the wrong angle. (So I wouldn't recommend Thread.Interrupt either, although at least it doesn't raise exceptions asynchronously.)

The approach I always recommend is dead simple. Have a volatile bool field that is visible both to your worker thread and your UI thread. If the user clicks cancel, set this flag. Meanwhile, on your worker thread, test the flag from time to time. If you see it get set, stop what you're doing.

The issue most people initially have with this approach is that it doesn't forcibly stop the thread in whatever it's in the middle of. That's actually a good thing though - it's much easier to keep your program's internal state consistent if you get to choose when to abort an operation. And in any case, if you're concerned about how long it will take for an operation to grind to a halt, just pretend to the user that it has been cancelled as soon as they click cancel, and then let it grind to a halt on the worker thread in its own sweet time. Of course, in some scenarios you will actually need to make the user wait until you've managed to stop the operation, but in the cases where there's no good reason to do this, just relax and let things come to a halt in their own time.

Alternative Non-Evil Cancellation

There is a completely different approach you can take: use processes. If you fire up an entirely seperate process to do the background work, then you can nuke it with impunity, because you don't care about its internal state, and it won't affect your process's internal state. (Although if it modifies persistent state you still need to take care to leave it in a persistent state.)

It feels pretty stone-age if you're used to using multiple threads, because it's so much effort marshalling data into and out of the remote process, but it is a workable approach. It also allows the child process to be incredibly shabby about releasing resources because it knows it's not going to live long. The main problem is that processes are relatively heavyweight on Windows. So for those two reasons, I tend to prefer the in-process solution.

Monday, January 30, 2012

Microsoft.Web.Administration in IIS 7

While creating the new administration stack in IIS 7, we were looking into the different ways users could manipulate the server configuration as well as the new runtime information available in IIS 7 (Internally we call this RSCA-Runtime State and Control API) from managed code, and we realized we needed to provide a simpler and more straight forward API that developers could consume from managed code. Microsoft.Web.Administration is the answer to this problem. This API is designed to be simple to code against in an “intellisense-driven” sort of way. At the root level a class called ServerManager exposes all the functionality you will need.

To show the power and simplicity of this API, let’s look at some samples below. To try this samples just create a new Console Application in Visual Studio and add a reference to Microsoft.Web.Administration.dll that can be found at IIS directory (%WinDir%\System32\InetSrv).
Please note that the following code is based on Windows Vista Beta 2 code and will likely change for the release candidate versions of Windows Vista since we have planned several enhancements to simplify the API and expose more features into it.
The following picture shows the main objects (excluding Configuration related classes).

Microsoft.Web.Administration
Creating a Site

ServerManager iisManager = new ServerManager();
iisManager.Sites.Add("NewSite", "http", "*:8080:", "d:\\MySite");
iisManager.Update();

This basically creates an instance of the ServerManager class and uses the Add method in the Sites collection to create a new site named "NewSite" listening at port 8080 using http protocol and content files are at d:\MySite.
One thing to note is that calling Update is a requirement since that is the moment when we persist the changes to the configuration store.
After running this code you have now a site that you can browse using http://localhost:8080

Adding an Application to a site
ServerManager iisManager = new ServerManager();
iisManager.Sites["NewSite"].Applications.Add("/Sales", "d:\\MyApp");
iisManager.Update();


This sample uses the Sites collection Indexer to get NewSite site and uses the Applications collection to add a new http://localhost:8080/Sales application.

Creating a Virtual Directory
ServerManager iisManager = new ServerManager();
Application app = iisManager.Sites["NewSite"].Applications["/Sales"];
app.VirtualDirectories.Add("/VDir", "d:\\MyVDir");
iisManager.Update();


Runtime State and Control

Now, moving on to the new Runtime state and control information we also expose in this objects information about their current state as well as the ability to modify them. For example, we expose the list of W3WP processes running (Worker processes) and what I think is really cool, we even expose the list of requests currently running. Stopping a Web Site
ServerManager iisManager = new ServerManager();
iisManager.Sites["NewSite"].Stop();

Recyciling an Application Pool
ServerManager iisManager = new ServerManager();
iisManager.ApplicationPools["DefaultAppPool"].Recycle();

Getting the list of executing requests
ServerManager iisManager = new ServerManager();
foreach
(WorkerProcess w3wp in iisManager.WorkerProcesses) {
Console.WriteLine(
"W3WP ({0})", w3wp.ProcessId);

foreach
(Request request in w3wp.GetRequests(0)) {
Console.WriteLine(
"{0} - {1},{2},{3}",
request.Url,
request.ClientIPAddr,
request.TimeElapsed,
request.TimeInState)
;
}
}

Another big thing on this API is the ability to edit the “.config” files using a simple API, this includes the ability of modifying the main applicationHost.config file from IIS, web.config files from asp.net as well as machine.config and other config files (such as administration.config)

Basic Threading in C#

Threading is a great way to make your application smoother. A single thread in a C# application, is an independent execution path that can run simultaneously with the main application thread. Of course, C# supports multithreading. And to use the threading namespace, you can directly call it from System.Threading, or import it:

1
using System.Threading;

Without this, a basic HTTP request makes your application unavailable in a span of time. And if you are using a progress bar, you won’t see it updating (since the application is unresponsive at this state).

Single Thread

The most basic way to implement this, is by using the Thread class. An example:

1
2
Thread tMain = new Thread(new ThreadStart(someMethod));
tMain.Start();

Wherein someMethod is a void function that contains the code you want to execute. With this, the thread will execute in parallel with the main thread. The only drawback, is you cannot modify controls created in the main thread like you normally use to. This will result into a Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on exception. The solution is pretty simple:

1
2
3
4
5
// Won't Work
textBox1.Text = "Hello";
// Will Work
this.Invoke(new MethodInvoker(delegate { textBox1.Text = "Hello"; }));

This approach functions just the same as a BackgroundWorker instance.

Powertip: You can disable all the controls in your form painlessly without setting the Enabledproperty of each control (imagine having 20+ controls in your form).

1
2
3
4
5
6
7
private void controlsEnableToggle(bool val)
{
foreach (Control c in this.Controls)
{
c.Enabled = val;
}
}

Multiple Threads

Dealing with multiple repetitive tasks with a single line of execution is painful, especially in large numbers. C# supports multithreading. This means, we can initiate as many threads as we like, and it will do the job. So how to do that? A simple for-loop.

1
2
3
4
for (int i = 0; i < 10; i++) {
Thread tMain = new Thread(new ThreadStart(someMethod));
tMain.Start();
}

The above code works, but what if we need to supply parameters to our method?

01
02
03
04
05
06
07
08
09
10
11
// .NET 2
for (int i = 0; i < 10; i++) {
Thread tMain = new Thread(new ParameterizedThreadStart(someMethod));
tMain.Start(param);
}
// .NET 3.5 & 4
for (int i = 0; i < 10; i++) {
Thread tMain = new Thread(unused => someMethod(param));
tMain.Start();
}

Pausing and Stopping Threads

Whenever you close a form, the main thread will stop, but the threads you created are not. Thus, the process is still alive. To stop this, you can just go to the task manager, and end the process from there. But that’s not user-friendly.

You cannot actually stop or pause threads immediately. You can never tell what the thread is doing, and terminating them abnormally may cause side effects. For this, ManualResetEvent is used.

1
2
ManualResetEvent pauseEvent = new ManualResetEvent(true);
ManualResetEvent stopEvent = new ManualResetEvent(false);

The bool values passed to the constructor indicates whether the initial state of the instance is signaled or not. This is pretty easy to use.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
ManualResetEvent pauseEvent = new ManualResetEvent(true);
ManualResetEvent stopEvent = new ManualResetEvent(false);
private void someMethod(string param) {
// Stops the thread
if (stopEvent.WaitOne(0))
return;
// Pauses the thread
pause Event.WaitOne(Timeout.Infinite);
// Your code
}

To change the signaled state of these events, we will use Reset and Set methods. Here’s how to use them in relation to the above code:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
// Stops the threads
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
stopEvent.Set();
}
// Pauses the threads
private void Button1_Click(object sender, EventArgs e)
{
pauseEvent.Reset();
}
// Resumes the threads
private void Button2_Click(object sender, EventArgs e)
{
pauseEvent.Set();
}

You can choose how you will use the methods, the above is just an example.