Well apparently being surrounded by family members kills my productivity. Who would have guessed, but I'm back from my vacation and have a couple posts lined up. Anyway, on Christmas I actually made a post showing some of the updates that were made to the tasks code for the LMS. This is a continuation of that, but one that might actually be interesting as I actually created a task that does something.
I read a ton of RSS feeds (and podcasts). Well, really only 50 feeds and 15 podcasts but many of them are aggregators of various sources. Anyway, I really want the system to aggregate all of those for me. That's not exactly something that you want running every time you process input by the user. Instead it's best done in the background every couple of minutes. So keeping that in mind, I thought it would be a good example of the task system:
#region Usings
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Core.Tasks.Interfaces;
using Utilities.FileFormats.RSSHelper;
using System.Xml;
#endregion
namespace Tasks
{
/// <summary>
/// Task designed to handle updating of RSS feeds
/// </summary>
public class RSS : ITask
{
#region Constructor
/// <summary>
/// Constructor
/// </summary>
public RSS()
{
}
#endregion
#region ITask Members
public void Process()
{
try
{
XmlDocument Document = new XmlDocument();
Document.LoadXml(Utilities.FileManager.GetFileContents(new Uri("http://www.codeproject.com/webservices/articlerss.aspx")));
Document Helper = new Document(Document);
Utilities.FileManager.SaveFile(Helper.ToString(), Core.CoreManager.Instance.SettingsInfo.DataDirectory + "Feeds\\CodeProject.xml");
}
catch { }
}
public int Timer
{
get { return 60000; }
}
#endregion
}
}
The code above only loads one feed, specifically Code Project's feed using my RSSHelper set of classes in my utility library. If you haven't been to that site before (Code Project), definitely check it out as there are a ton of articles/code snippets. Very useful. Anyway, once it loads it, it simply saves it to the data directory (under feeds). That's it. It's simple, easy, and buggy as hell. You may surprised to hear me say that, but it has a huge bug. In fact I knew that I was creating this bug when I first started the project. I mean it's not the worker thread code as that works quite well. It's not the RSSHelper or FileManger classes (I mean I'm certain they have bugs but that's not the huge issue here). So what is it? If you're stumped you may want to go back to the first post and try to figure out what the issue would be, I'll wait.
Ok, maybe I wont wait or perhaps you just didn't go back to read it. Or perhaps it just didn't jump out at you... Anyway, the answer is actually pretty simple, you see I used a singleton for the main class CoreManager. You call the Instance variable and it creates a new instance. The only instance... Well sort of... That may not make sense, so let me explain. When you create a DLL, normally you just link it as a reference in the main project (or where ever). When you do this, that DLL is linked at build time. However I'm dynamically loading the DLLs at run time. In the statically linked version, the memory space is the same as the main app. In the dynamically linked version, the memory space is seperate from the main app. So we create the instance of the CoreManager in the main app and that creates the various tasks. But when the RSS task tries to use the CoreManager, there is no instance of the object in its memory space, so it creates a new instance. This loads everything over again and potentially again and again... Not the best thing in the world, but there is an easy fix. All it takes is passing in the original CoreManager object and using that. Fairly simple. It kills the whole singleton idea, but hey it works.
Anyway, this post is a bit short, I know, but I wanted to show everyone why a singleton is not necessarily the best thing in the world. I'm not saying that you shouldn't ever use them, just that you should know that they have pitfalls. So take a look, leave feedback, and happy coding.
9e162cbc-3e96-497c-8662-f7723d3cd3b4|0|.0