Scheduling and Event Logging Windows Service

In previous post we had seen how to create a windows service. In this part we will see how can we log events in windows service and how to schedule service to occur at specific interval.



First we will see how we can Log events in EventViewer event of Windows Service. Steps are as follows.

- Add an EventLog to your windows service class, from Toolbox.

- Give an ID say "MyEventLog1", Set Log to "MyEventLog" and Source to "MyEventLogSource"



This will help you to differentiate your log in event viewer. And you can also create a new view of your event source log. Create new Log View on application and rename it to "MyEventLogSource". Now clear logs, then each new entry with log source "MyEventLogSource" will be logged in the new view.



Now how will we write a new log entry in Windows Service.

Write the following code in OnStart Code block of your Service.



MyEventLog1.WriteEntry("My Windows Service Started.......");



This will be write a log entry. But make sure that you write this code in try-catch block, because on some OS, Windows Service do not have permission to log events. At that time your service will generate an unhandeled exception and it will stop immediately and you will unable to identify the problem that why your service is stopped immediately after it starts.





There can be two types of windows service.

1) Windows service that run only once. There is no any scheduling of the service. If you want to run it again the you must start the service again. It will stop automatically after it complete its job.



2) Windows service that run at specific interval. This service is useful to run Insert command from one server to other backup server. Or it can be use to complete tasks that are added in Database.



The first type of Windows service is very easy. Just put your code in OnStart event of the Windows Service.




Scheduling Windows Service with Timer Control

For scheduling a Windows service declare two global variables in your service class (Make sure not in Service.designer.cs Designer class)
This timer control is not System.Timer, this control is
System.Threading.Timer



private Timer stateTimer;

private TimerCallback timerDelegate;



Timer is useful for creating the scheduling the Service. TimerCallback is useful for specifying the function which will be called when timer interval ends(Tick event fires).



Now write this code in your OnStart block.

timerDelegate = new TimerCallback(DoSomething);
stateTimer = new Timer(timerDelegate, null, 0, 5000); // 5000 = 5 secs

In above code the timerDelegate is a callback function which will specify the Function that will be called each time your timer fires tick event.

Now the stateTimer is assigned to a new timer object which specify timerDelegate, initial delay and interval. In above example '0' is initial delay which specify after timer object is created how much to delay for firing first Tick event. '5000' this specify the interval, this indicate the delay of firing the tick event since the last tick event is fired. Both Initial delay and Interval are specified in milisecond.


Now we will see how to create the function.

protected void DoSomething(object sender)
{
MyEventLog1.WriteEntry("Windows Service event fired at " + DateTime.Now.ToString());
}

Above I have specified the function to be fired at tick event of timer. It will log in EventViewer with date and time.


In next part we will see how can we add a configuration file to the Windows Service, how to install the service and common problem while using with Windows Server 2003 system.

Resizing Data Controls in ASP.NET Applications

Introduction

This article explains about resizing web controls in runtime. In browser output, usually resizing is achieved during Development for fixing the control’s width and height. But sometimes we require resizing the DataGrid, DataList or other data controls to adjust for clearly reading the displayed data. It is rare to see the internet page's output to be adjustable, but it is possible with a few lines of JavaScript.

Event Types

The whole resize logic (column width increase or decrease) depends upon catching the co-ordinate where the user drags the column to be resized. Mouse capturing will be set on initially when the page loads. Events to be captured are the following:

· Mouse Over

· Mouse Down

· Mouse Up

Style Settings

Resizing can be done only on the column headers. Usually all data controls, like DataGrid, GridView or DataList, will be set with some style class for the header row. Here we take advantage of this style for tracking the user's mouse over an event on the header row. This event will initiate the trigger to start capturing the further events like mouse down and mouse up. There is no special style setting to be done other than the user’s look and feel styles. The JavaScript just requires a style name and that is it!

Mouse Capturing

The user will be automatically seeing the difference in the cursor which will signal to them that the DataGrid/GridView is ready for resizing. This will be done by the handler which we have set for document onmousemove. Whenever the user reaches the header row, the first level job is over and mouse down event will be ready to be raised for checking where the user clicks the mouse to start dragging. At this moment the mouse move event will again take over. Now the JavaScript will start handling mousedown and mousemove, which is equal to mouse drag. On the mouse drag, the column size and the table size will increase or decrease based on the mouse’s left or right movement respectively. Whenever the user makes the mouse go up (stops dragging and releasing the mouse), the resizing will get stopped and the current drag object will be destroyed.

More Technical Information on Events


There are some things to look into in the code for a clearer understanding. The column resize can be pulled into the picture by just adding the JavaScript file to the web page. Before that, define the header columns you use in the web pages to the JavaScript file (headerStyle).

Listing 1

var isDraggable = false;
var xX=0;anchorChild=0;anchorMain=0;
var objOn=null;gridMain=null;
var lastObj=undefined;
var headerStyle="DataGrid-HeaderStyle";

Other common settings to be made are the following:

isDraggable – This variable will be initially set to false to denote that dragging logic should not be called; this will become true whenever the mouse hovers over the datagrid’s header column’s border.

xX, anchorChild, anchorMain – These three variables will hold 0 initially on every mouse down event when the user starts dragging. xX will hold the x-axis position of the mouse, anchorChild will hold the width of the Current Resizing cell, and anchorMain will hold the width of the entire DataGrid or control.

objOn – This will hold the current object which is under dragging.

lastObj – This temp object loads the objOn object. This will be captured on mousedown and loaded to objOn during MouseMove.

Firefox – DOM Expressions differ from browser to browser, so we have a common variable which will be checked in every event. When the script is initialized, we initialize the FireFox by finding whether the current browser is Firefox or other.

Listing 2

var firefox = document.getElementById&&!document.all; 

Mouse Events

OnMouseMove – This event is used to capture the current place in which the mouse is hovered and also to change the width of the cell and DataGrid while they drag. So first we will capture the object on which we hover the mouse.

Listing 3

objOn=(!firefox)?e.srcElement:e.target; 

The line below will be used to load the last mouse over the object for reference.

Listing 4

if(lastObj!=undefined)objOn=lastObj; 

Then we have to change the cursor to resizable if the mouse is hovered on the DataGrid header column’s borders.

Listing 5

document.body.style.cursor =(objOn.offsetWidth-e.offsetX < 10 &&
objOn.parentElement.className == headerStyle)?'e-resize':'default';

Now, we decide whether we should start dragging or not. It depends on whether the user has clicked the mouse for dragging which would have made the boolean isDraggable true.

Listing 6

if(isDraggable)
{ document.body.style.cursor='e-resize';
//Current_MouseX_Position - MouseX_DragStart + Cell_Width
ic=e.clientX-xX+anchorChild;
//Current_MouseX_Position - MouseX_DragStart + Table_Width
it=e.clientX-xX+anchorMain;
if(ic>0)
{
gridMain.style.width = it + "px"; //Increase Table Width
objOn.style.width = ic + "px"; //Increase Cell Width
}
}

The above piece of code will increase or decrease the size of the DataGrid based on the mouse movement.

OnMouseDown – This event is used to capture the point or pixel where the user has started to drag (if the user has the mouse pointer over the DataGrid header’s border). Here we will find the Cell’s Offset Position and Table’s Offset position which will give the current X-Axis width of the cell and the table respectively.

First we will capture the object over which we hover the mouse.

Listing 7

objOn=(!firefox)?e.srcElement:e.target; 

Then we have to check whether the mouse is hovered on the DataGrid header column’s borders. If it is true, the following steps will be carried out.

Listing 8

if(objOn.parentElement.className == headerStyle &&
document.body.style.cursor=='e-resize')
{

Set the Boolean Flag isDraggable to denote that we are in draggable mode.

Listing 9

isDraggable = true; 

Set the gridMain object with the DataGrid or GridView object.

Listing 10

gridMain = objOn.parentElement.parentElement.parentElement; 

Get the object of main table which corresponds to current column's width variation.

Listing 11

xX = e.clientX; 

Get the current Mouse X Position.

Listing 12

anchorChild = objOn.offsetWidth; 

Getting the current Cell/Column Width

Listing 13

anchorMain = gridMain.offsetWidth; 

Get the current Table Width.

Listing 14

lastObj = objOn; 

This will be the else part of the Current IF Statement. If the mouse is clicked outside the header scope, the lastObj variable is set to undefined.

Listing 15

lastObj = undefined;

OnMouseUp – This event is used to stop the dragging. There is no specific code to stop the drag; the drag event will be fired based on mouseover and mousedown events. When the mouse click is up, lastObj object used in those events will be undefined and isDraggable boolean flag will be set to false to say that the drag has been stopped by the user.

Dragging Stop and Forget LastObj

Listing 16

isDraggable = false;
lastObj=undefined;

Here is full JavaScript Code

var firefox = document.getElementById&&!document.all; //Check whether the browser is FF;
var isDraggable = true;
var xX=0;anchorChild=0;anchorMain=0;
var objOn=null;gridMain=null;
var lastObj=undefined;
var headerStyle="DataGrid-HeaderStyle";

document.onmouseup=mouseUpCapture;

document.onmousemove=mouseMoveCapture;

document.onmousedown=mouseDownCapture;

/*EventHandler to capture Mouse Up*/

function mouseUpCapture(){isDraggable = false;lastObj=undefined;} //Dragging Stop and Forget LastObj;


/*EventHandler to capture Mouse Down*/

function mouseDownCapture(e){

if(!firefox)e = event;objOn=(!firefox)?e.srcElement:e.target; //Check whether the browser is FF and set event object accordingly;

//To Check whether the mouse hovers over the HeaderRow and cursor type is currently re-sizable;

if(objOn.parentElement.className == headerStyle && document.body.style.cursor=='e-resize')
{

isDraggable = true; //Start understanding that we can start dragging;
gridMain = objOn.parentElement.parentElement.parentElement; //Getting the object of main table which corresponds to current column's width variation;


xX = e.clientX; //Getting the current Mouse X Position;

anchorChild = objOn.offsetWidth; //Getting the current Cell/Column Width;

anchorMain = gridMain.offsetWidth; //Getting the current Table Width;

lastObj = objOn; //Stores the current mouse hovering object for moving reference;

}

else{lastObj = undefined;}
}

/*EventHandler to capture Mouse Move*/

function mouseMoveCapture(e){

if(!firefox)e = event; //Check whether the browser is FF and set event object accordingly;
objOn=(!firefox)?e.srcElement:e.target;

if(lastObj!=undefined)objOn=lastObj; //Loads the mouse hovered object for moving reference;

//Check whether the mouse hovers over the Headerrow's column borders and Make the cursor re-sizable;
document.body.style.cursor =(objOn.offsetWidth-e.offsetX < 10 && objOn.parentElement.className == headerStyle)?'e-resize':'default';

//Start Dragging
if(isDraggable)
{ document.body.style.cursor='e-resize'; //Maintaing the cursor as re-sizable
ic=e.clientX-xX+anchorChild;

//Current_MouseX_Position - MouseX_DragStart + Cell_Width;
it=e.clientX-xX+anchorMain;

//Current_MouseX_Position - MouseX_DragStart + Table_Width;

if(ic>0)
{
gridMain.style.width = it + "px"; //Increase Table Width;
objOn.style.width = ic + "px"; //Increase Cell Width;
}

}

}