Philippsen's Blog

Everyday findings in my world of .net and related stuff

Archive for October, 2010

Execute job within a Windows Service at a certain time

Posted by Torben M. Philippsen on October 28, 2010

Quite often I am asked to create a job to run within a windows service – the following demands applies:

  • A Windows Service is needed since the demands for applying a schedule is not met by the “Scheduled Tasks” features from Windows. Due to that a Console App is ruled out.
  • The job routine must be executed at a certain time – this must be configurable.
  • When the job routine has been executed a schedule must be started – this must be configurable.

To accomplish this we will use:

  • an app.config file to hold our configuration
  • Two Timers – remember to use System.Threading.Timer rather than the System.Windows.Forms.Timer

What we need to do is:

  • Create an OnStart event that starts the processing in a separate thread. This is always a good idea since you will avoid start problems if the process your are starting takes some time to finish.
  • Calculate the time from now and until the job is supposed to run. Start a timer with exactly that delay by setting the duetime of the Timer.
  • When the job executes… Create a new timer and set the Period of the Timer to correspond to the wanted schedule.

Here’s an example of one way to accomplish the task:

    1         protected override void OnStart(string[] args)

    2         {

    3             //Start the actual job in a separate thread to avoid timeouts on start

    4             backgroundWorker = new System.ComponentModel.BackgroundWorker();

    5             backgroundWorker.WorkerReportsProgress = false;

    6             backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);

    7             backgroundWorker.RunWorkerAsync();

    8         }

    9

   10         void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)

   11         {

   22             //the timer that initilizes that the job is executed for the first time at a certain time

   12             StartInitTimer();

   13         }

Let’s look at the StartInitTimer() method:

   30         ///<summary>

   31         /// Starts the initializing timer. this timer runs once and sets the aplicationlogic to run on the configured schedule

   32         ///</summary>

   33         private void StartInitTimer()

   34         {

   35             //calcuale the delay until the point of starting time

   36             DateTime start = DateTime.Parse(ConfigurationManager.AppSettings[“ImportStartTime”]);

   37             DateTime current = DateTime.Now;

   38             TimeSpan timeBeforeStart;

   39             if (start < current)

   40             {

   41                 //the starttime for today has passed – calculate the start time after midnight

   42                 DateTime midnight = GetMidnight();

   43                 TimeSpan timeBeforeMidnight = midnight.Subtract(current);

   44                 timeBeforeStart = timeBeforeMidnight.Add(new TimeSpan(start.Hour, start.Minute, start.Second));

   45             }

   46             else

   47             {

   48                 timeBeforeStart = start.Subtract(current);

   49             }

   50             //start the timer

   51             initTimer = new System.Threading.Timer(InitTimer_Elapsed, null, timeBeforeStart, new TimeSpan(0, 0, 0)); //setting timespan to -1 milliseconds causes the timer to run once

   52         }

   53

   54         ///<summary>

   55         /// Helper method – Calculates a datetime object for the next coming midnight

   56         ///</summary>

   57         ///<returns></returns>

   58         private DateTime GetMidnight()

   59         {

   60             DateTime midnight = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0);

   61             midnight = midnight.AddDays(1);

   62             return midnight;

   63         }

   64

   65         ///<summary>

   66         /// handles the elapsed event of the imitializing timer

   67         ///</summary>

   68         ///<param name=”sender”></param>

   69         ///<param name=”e”></param>

   70        private void InitTimer_Elapsed(object state)

   71         {

   72             //import is executed one time only in this eventhandler.

   73             try

   74             {

   75                 //Start the schedule

   76                 StartScheduleTimer();

   77                 //perform the job

   78                 DoSomething();

   79

   80             }

   81             catch (Exception ex)

   82             {

   83

   84             }

   85             finally

   86             {

   87                 //dispose the timer object – this timer has done it’s purpose

   88                 initTimer.Dispose();

   89             }

   90

   91         }

  100         private void StartScheduleTimer()

  101         {

  102             //the interval in hours

  103             //                                                                                   s     m    h

  104             int timerInterval = int.Parse(ConfigurationManager.AppSettings[“TimerInterval”]) * 1000 * 60 * 60;

  105             scheduleTimer = new System.Threading.Timer(ScheduleTimer_Elapsed, null, timerInterval, System.Threading.Timeout.Infinite);

  106         }

  107

  108

  109         ///<summary>

  110         /// Every time the timer ticks – the ScheduleTimer_Elapsed method is triggered – the job stuff is being performed here

  111         ///</summary>

  112         ///<param name=”sender”></param>

  113         ///<param name=”e”></param>

  114         private void ScheduleTimer_Elapsed(object state)

  115         {

  116             //reset the timer – set the due/wait time until next event firing

  117             //                                                                                  s     m    h

  118             scheduleTimer.Change(int.Parse(ConfigurationManager.AppSettings[“TimerInterval”]) * 1000 * 60 * 60, System.Threading.Timeout.Infinite);

  119             //perform the job

  120             DoSomething();

  121         }

Posted in Windows services | Tagged: , | 7 Comments »

Service start problem – error 1053

Posted by Torben M. Philippsen on October 26, 2010

A collegue of mine reported that he experienced difficulties deploying af  .net 4.0 windows service. The installation process went just fine, but when trying to start the service he recieved the following error almost instantly:

Service start problem screenshot

Trying to get a grip on the cause of the error, the OnStart event of the service was left blank – and still the service failed to start.

Usuallly when a service fails to start and return error 1053 almost instantly, it is caused by a reference to an assemmbly which is not properly loaded. In this case only references to .net assemblies were created. Having installed the .net framework 4.0 should make you think that you are homefree – but that’s not necessarily the case. The secret lies in which target framework you choose to build your service on:

 select framework screenshot

In this case the .NET framework 4 was choosen, because some of the assmeblies used, were not included in the default “.NET Framework 4 Client Profile”. On the server where the service was deployed it turned out, that only the .net framework 4 client profile was installed. Now the solution was simple – we just had to install the extended version of the .Net framework.

Problem solved:-)

Posted in Windows services | Tagged: , , | Comments Off on Service start problem – error 1053

Copy source as Html in Visual Studio 2010

Posted by Torben M. Philippsen on October 25, 2010

For some time I’ve been looking for a good way to copy my source code into this blog, without having to install a plugin. I stumpled across this great article about how to enable “Copy source as html” in Visual Studio 2010. “Copy source as HTML” can be downloaded from codeplex – check it out.

 

Update: 2011-11-30

For some strange reasons “Copy Source as HTML” has stopped working and I am not able to get it up and running again. Instead of struggling any more than necessary I installed “Code4Blog“. It seems to work really great and even better than “Copy Source as HTML”.

Posted in Tools | Comments Off on Copy source as Html in Visual Studio 2010

FileSystemWatcher problem – file is in use by another process

Posted by Torben M. Philippsen on October 25, 2010

Recently I was developing a simple windows service that was supposed to monitor a certain folder for incomming xml files. When Xml files were received, the xml content should be send to a http endpoint – pretty straight forward.

The FileSystemWatcher was created like this:

    1  /// <summary>

    2         /// Creates a filesystem watcher listening for new xml files. An event is rised, if a new file is created in the watched folder

    3         /// </summary>

    4         private void CreateFileSystemWatcher()

    5         {

    6             watcher = new FileSystemWatcher();

    7             watcher.Path = ConfigurationManager.AppSettings[“xmlFilePath”];

    8             // Only watch xml files.

    9             watcher.Filter = “*.xml”;

   10             // Add event handlers.           

   11             watcher.Created += new FileSystemEventHandler(OnCreated);

   12             //watcher.Changed += new FileSystemEventHandler(OnCreated);

   13             // Begin watching.

   14             watcher.EnableRaisingEvents = true;

   15         }

 

The eventhandler looked like this:

   20         /// <summary>

   21         /// Eventhandler – handles the event where a new file is created in the watched folder

   22         /// </summary>

   23         /// <param name=”source”></param>

   24         /// <param name=”e”></param>

   25         private void OnCreated(object source, FileSystemEventArgs e)

   26         {           

   27             // Specify what is done when a file is created.

   28             XmlDocument doc = GetXmlDocumentFromFile(e.FullPath);

   29             StatusObj result = Post(doc);

   30             ProcessResult(result, e.FullPath, e.Name);           

   31         }

 

I quickly discovered that I would receive an exception when trying to read the xml content from the file that triggered the event. I found that the reason to this issue is that when the “create” event is triggered the file hasn’t finished to be written to the folder. The process that writes the file to the folder, will still have an active filehandle causing the “Access denied” exception.

In my search for a “good” solution I read that some would recomment to use the “change” event of the FileSystemWatcher. I haven’t been able to get this to work and You should be aware that using the change event will cause your eventhandler to trigger at least twice when a file is written to the monitored folder.
The best solution I found was to make a function that checks if the file can be read or not – something like this:
 

   40         /// <summary>

   41         /// Helper method used to check if the file has been released from the os

   42         /// </summary>

   43         /// <param name=”file”></param>

   44         /// <returns></returns>

   45         public bool IsFileInUse(FileInfo file)

   46         {

   47             FileStream stream = null;

   48             try

   49             {

   50                 stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);

   51             }

   52             catch (IOException)

   53             {

   54                 //the file is unavailable because it is:

   55                 //still being written to

   56                 //or being processed by another thread

   57                 //or does not exist (has already been processed)

   58                 return true;

   59             }

   60             finally

   61             {

   62                 if (stream != null)

   63                     stream.Close();

   64             }

   65             //file is not locked

   66             return false;

   67         }

 

And then use it like this:

   80         /// <summary>

   81         /// Reads the xml structure from the physical file into a XmlDocument object

   82         /// </summary>

   83         /// <param name=”filename”>the full path of the xmlfile</param>

   84         /// <returns></returns>

   85         private XmlDocument GetXmlDocumentFromFile(string filename)

   86         {

   87             XmlDocument xDoc = new XmlDocument();

   88             while (IsFileInUse(new FileInfo(filename)))

   89             {

   90                 //loop until filehandle is released

   91                 Thread.Sleep(500);

   92             }

   93             try

   94             {

   95                 xDoc.Load(filename);

   96             }

   97             catch (Exception ex)

   98             {

   99             }

  100             return xDoc;

  101         }

I know that using exception handling to control a certain flow isn’t concidered best practice – but unfortunately this was the best I could come up with. Should You have a better way – please leave a note…


Posted in System.IO | Tagged: , | 2 Comments »

Reporting Services – rsAccessDenied error

Posted by Torben M. Philippsen on October 13, 2010

Today I had to prepare a new SQL Server Reporting Services installation for a workshop I will be giving this friday. I’ve performed this task a lot of times but always on “real” server OS’s – never on a desktop OS, which this has to be.

The installation went pretty much by itself, but after runing the Reporting Services Configuration Manager and opening http://localhost/reports I got the following error:

The permissions granted to user ‘domain\username’ are insufficient for performing this operation. (rsAccessDenied)

After some googling I finally found a solution that I thought I would share:

  • Make sure you have access configured to the URL http://localhost/reports using the SQL Reporting Services Configuration. To do this:
  • Open Reporting Services Configuration Manager -> then connect to the report server instance  -> then click on Report Manager URL.
  • In the Report Manager URL page, click the Advanced button -> then in the Multiple Identities for Report Manager, click Add.
  • In the Add a Report Manager HTTP URL popup box, select Host Header and type in: localhost
  • Click OK to save your changes.
  • Now start/ run Internet Explorer using Run as Administator…  
  • NOTE: If you don’t see the ‘Site Settings’ link in the top left corner while at http://localhost/reports it is probably because you aren’t running IE as an Administator or you haven’t assigned your computers ‘domain\username’ to the reporting services roles, see how to do this in the next few steps.
  • Then go to: http://localhost/reports   (you may have to login with your Computer’s username and password)
  • You should now be directed to the Home page of SQL Server Reporting Services here: http://localhost/Reports/Pages/Folder.aspx
  • From the Home page, click the Folder Settings tab, then click New Role Assignment
  • In the Group or user name textbox, add the ‘domain\username’ which was in the error message (you can find the domain\username for your computer in the rsAccessDenied error message).
  • Now check all the checkboxes; Browser, Content Manager, My Reports, Publisher, Report Builder, and then click OK.
  • You’re domain\username should now be assigned to the Roles that will give you access to deploy your reports to the Report Server.  If you’re using Visual Studio or SQL Server Business Intelligence Development Studio to deploy your reports to your local reports server, you should now be able to.

Just to let You know, this solution applies to windows 7 running SQL Server 2008 Developer Edition

Posted in Reporting Services | Tagged: , | 1 Comment »

Free e-books

Posted by Torben M. Philippsen on October 12, 2010

Som free e-books that I stumbled accross in the latest edition of the MSDN Flash:

Foundations Of Programming

The Foundation Of Programming Series Free e-book By Karl Seguin. It is simple, short and sweet. Especially for ‘casual’ programmers, this will give a better thought process – that’ll definitely enable them to code better and think better. This book covers the ALT.NET Philosophy, Domain Driven Development concepts, DI, TDD etc in a nice way.

Microsoft Application Architecture Guide, 2nd Edition

Published by Microsoft, this is an essential read for any Microsoft.NET developer or Architect to understand the underlying architecture and design principles and patterns for developing successful solutions on the Microsoft platform and the .NET Framework. This guide neatly covers popular architecture patterns, best practices and common challenges you need to understand for developing .NET applications. Get a good grip on developing enterprise applications in .NET.

Rob Miles C# Yellow Book 2010

A nice action packed book that takes you through C# and .NET concepts. This book explains C# language and .NET library in general – with a clear focus on implementation thought process and best practices.

Threading in C#

A short, neatly written book from Joe Albahari about Threading in C#. This is a must read for any .NET programmer to understand more about threading in general, thread pooling, synchronization, Non blocking synchronization, etc. In this book, Joe even covers the Parallel Framework Extensions and Parallel programming in .NET

Improving .NET Application Performance and Scalability

This guide is again from Microsoft, and focuses on designing your applications with Performance and scalability in mind. It has sections relevant to architects, developers, testers, and administrators. Following the checklists and guidance in this book will ensure that there won’t be any unpleasant surprises in the end. Read this guide if you develop Enterprise applications in .NET

Applying Design Patterns

This is a quick introduction towards the thought process of applying design patterns. The objective of the book is to introduce design patterns in a simple way, so that developers can understand some common patterns and how to apply them.

RefCardz from DZone

DZone has a number of awesome Ref Cardz (Quick reference sheets) on multiple technologies. You can go to DZone –> RefCardz to browse and download them (after getting a free DZone Id). Here are some of my favorites:

Posted in Books and reading stuff | Tagged: | Comments Off on Free e-books

 
%d bloggers like this: