One of my tasks recently has been building a service for SharePoint 2007. The idea is that this service would read a set of items in a list, apply some rules, and send out a notification email to various users as a sort of ‘digest’ of things that they needed to deal with. In the end, I produced a Windows service to do this – but there clever folks like Colin Byrne and Andrew Connell who’re starting to figure out how build ‘services’ (or ‘jobs’) into SharePoint 2007 directly, and I suspect this overcomes some of the issues I found.
Right, some context. The customer needed something straight forward – notification emails to be send out to users about the items on this list. Initially, the plan was to use the workflow in MOSS for this. Sure, doing ‘digest’ emails would require a custom step – and I still think that this would be a good feature to have – but that all seemed possible. (By digest email, I mean having one email which said ‘You have 3 items deal with – A, B and C’, rather than seperate emails for each one’)
However, the Delay steps in Beta 2 TR – which we were supposed to be releasing onto – didn’t seem to work properly. Certainly, I had consistent problems with them – see elsewhere on this blog, and I know that other developers have posted describing the same problem – they just never return from ‘sleeping’.
So, ultimately we ditched workflow due to time constraints – which is a real shame, as I think it’s great. Anyway, I then looked at having some sort of timed job or similar. I’ve built these for Open Text’s Livelink system, and it’s pretty straight forward there. I thought it couldn’t be hard for SharePoint 2007. Well, it isn’t, but there wasn’t any documentation or blog postings out there about it – and time was pressing now.
I then looked at how you’d do this for SharePoint 2003 – and as Andrew Connell notes, this was a scheduled .exe (uck) or a Windows Service (a little less uck).
(Actually, a digression here – I don’t actually mind CRON jobs. In some ways I’m a bit of a luddite, so just saying ‘run this command at this time’ is the sort of thing that appeals to me over more sophisticated (and complex) approaches like, well, Windows Services. However, I detest the user interface for Windows Scheduled tasks. The wizard doesn’t make all the options available to you obvious. You can’t edit the main features of the tasks in an ‘Excel like’ view. If you do want to edit properties, it item-by-item, with lots of flicking between tabs. And part of me rather thinks that some sort of calendar view might be useful – especially if you could get a consolidated view from across numerous servers! )
Back to the point. So, I built a Windows service, and it worked. Sadly, though, it had a huge memory footprint – 60Mb! This is acceptable when it’s actually doing something, perhaps, but not for the hours it spends waiting between sending these emails.
Eventually, I realised what was happening. To access the SharePoint object model, the service was using the Microsoft.SharePoint DLL. This in turn was loading other SharePoint assemblies. Next thing you know, it’s loaded 60Mb into the application domain – and the stuff remains there until the service is restarted.
The answer to that was to pull all the bits that use the SharePoint assemblies into a separate application domain, and have the service load, use and unload that app domain.
Anyway, in hindsight:
- I would use a windows scheduled task for this rather than a service. This is despite the fact that the service can be administered more easily.
- I would use the SPJobDefinition to create a service in SharePoint itself rather than either of the other two approaches.
- It’s obvious that the SharePoint dll was going to cause other assemblies to be loaded and to use up lots of memory. It’s worth remembering that, and avoiding having them sit in memory if not doing anything.