4

I need to check the status of a VS workflow a number of times for status and send email if task incomplete. Usually I create a Sharepoint timer Job. As I am required to check numerous times a day 10.30, 16:00, 1800 mon-fri and 10.30,12:00 Saturday. Would it be better to create a Console Application ?

Someone mentioned a timer job would be better. i.e instantiate the timer job for every period. But I dont know how to do this from VS. I created a feature that adds and removes the timer job within VS .

Any guidance appreciated.

UPDATE :

I see your point about registering multiple jobs in the code. Could you possibly have a look at code for me pls, this is the feature as part of tutorial. http://dotnetfinder.wordpress.com/2010/07/24/creatingcustomsharepointtimerjob2010/

namespace DT_CustomTimer.Features.Feature1

{ /// /// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade. /// /// /// The GUID attached to this class may be used during packaging and should not be modified. ///

[Guid("a959005c-5ab7-49fe-934e-5c79b339907f")]
public class Feature1EventReceiver : SPFeatureReceiver
{
    const string List_JOB_NAME = "ListLogger";
    // Uncomment the method below to handle the event raised after a feature has been activated.

    public override void FeatureActivated(SPFeatureReceiverProperties properties)
    {
        SPSite site = properties.Feature.Parent as SPSite;

        // make sure the job isn't already registered

        foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
        {

            if (job.Name == List_JOB_NAME)

                job.Delete();

        }

        // install the job

        DT_TimerJob listLoggerJob = new DT_TimerJob(List_JOB_NAME, site.WebApplication);

        SPMinuteSchedule schedule = new SPMinuteSchedule();

        schedule.BeginSecond = 0;

        schedule.EndSecond = 59;

        schedule.Interval = 5;

        listLoggerJob.Schedule = schedule;

        listLoggerJob.Update();
    }


    // Uncomment the method below to handle the event raised before a feature is deactivated.

    public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
    {
        SPSite site = properties.Feature.Parent as SPSite;

        // delete the job

        foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
        {

            if (job.Name == List_JOB_NAME)

                job.Delete();

        }
    }


    // Uncomment the method below to handle the event raised after a feature has been installed.

    //public override void FeatureInstalled(SPFeatureReceiverProperties properties)
    //{
    //}


    // Uncomment the method below to handle the event raised before a feature is uninstalled.

    //public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
    //{
    //}

    // Uncomment the method below to handle the event raised when a feature is upgrading.

    //public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
    //{
    //}
}

}

3 Answers 3

2

Here is an article to help create a timerjob: http://dotnetfinder.wordpress.com/2010/07/24/creatingcustomsharepointtimerjob2010/

In my opinion, you should try to use SharePoint timer jobs over console apps where ever possible.

I think you should build it as a timer job. Run it every so often (say every 30 minutes).

When the timer job runs, it should check a configuration to see whether it should continue to perform the task. The mentioned configuration will define when the the timer job to should check the status of the workflows.. The configuration will be formed as an array of DateTime objects. You can a SPPersistedObject to store such configuration object.

Here is what I expect the Configuration SPPersistedObject to look like.

public class MyTimingSettings : SPPersistedObject {

    [Persisted]
    protected string _serializedTimesToRun;

    private const string MY_OBJECT_NAME = "MyTimingSettings";

    public MyTimingSettings()
    {
    }

    private MyTimingSettings(SPPersistedObject parent)
        : base(MY_OBJECT_NAME, parent)
    {
    }


    public MyTimingSettings(string name,SPPersistedObject parent) : base(name,parent)
    {

    }

    public List<DateTime> TimesToRun
    {
        get
        {
            return DeserializeFromXML<List<DateTime>>(_serializedTimesToRun);

        }
        set { _serializedTimesToRun = SerializeToXML<List<DateTime>>(value); }
    }



    public static MyTimingSettings Local
    {
        get
        {
            SPPersistedObject parent = SPFarm.Local;
            var obj = parent.GetChild<MyTimingSettings>(MY_OBJECT_NAME);
            if (obj == null)
            {
                obj = new MyTimingSettings(parent);
                obj.Enabled = false;
                obj.Update();
            }

            return obj;
        }
    }


    public static string SerializeToXML<T>(T adSource)
    {
        XmlSerializer serializer = new XmlSerializer(typeof(T));
        StringBuilder sb = new StringBuilder();
        TextWriter textWriter = new StringWriter(sb);
        serializer.Serialize(textWriter, adSource);
        textWriter.Close();
        return sb.ToString();
    }

    public static T DeserializeFromXML<T>(string xml)
    {
        XmlSerializer deserializer = new XmlSerializer(typeof(T));
        TextReader textReader = new StringReader(xml);
        T adSource;
        adSource = (T)deserializer.Deserialize(textReader);
        textReader.Close();
        return adSource;
    }

}

In your timer job, you can call your configuration by the following code:

MyTimingSettings myTimingConfigurations = MyTimingSettings .Local;

You can then write an application page to manage your MyTimingSetting object. I'll leave that to you to figure out. :)

Also make sure you set the some default values for the timing configurations.

Hope this helps.

0

You can simply create a windows app to register your job instances, can't you? And even in the feature receiver code you can register multiple job instances. What's the problem that prevents you from registering multiple job instances in code? All you need to ensure is the unique job instance names - see the "Naming a Timer Job" section here.

0

You can register multiple instances of your timer job which will run according to the schedules you specified. I have developed a sample code for such routine in FeatureActivated method. This routine runs a timer job on following minutes within an hour :

1;5;10;15;20;25;30;35;40;45;50;55;

  public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
            // register the the current web
            SPSite site = properties.Feature.Parent as SPSite;
            string name = "My Job";
            string beingminutes = "1;5;10;15;20;25;30;35;40;45;50;55";
            try
            {

                if (String.IsNullOrEmpty(beingminutes))
                    throw new SPException("Please enter the schedule for timer job.");

                // make sure the job isn't already registered
                foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)
                {
                    if (job.Name.StartsWith(name))
                        job.Delete();
                }
                SPServer server = SPServer.Local;
                // install the job
                string[] startingTimes = beingminutes.Split(';');
                int index = 0;
                for (index = 0; index < startingTimes.Length; index++)
                {
                    int startingTime = Convert.ToInt32(startingTimes[index]);
                    // install the job   
                    DT_TimerJob listLoggerJob = new DT_TimerJob(name, site.WebApplication);

                    SPHourlySchedule schedule = new SPHourlySchedule();
                    schedule.BeginMinute = startingTime;
                    schedule.EndMinute = startingTime;
                    listLoggerJob.Schedule = schedule;
                    listLoggerJob.Update();
                }

            }



            catch (Exception ex)
            { }

            finally { site.Dispose(); }




        }
1
  • where is exportJob defined? do you meant listLoggerJob?
    – Snickbrack
    Commented Sep 8, 2016 at 6:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.