This project has moved. For the latest updates, please go here.

Crash on Edit Task using TaskEditDialog

Topics: Errors
Aug 6, 2014 at 11:00 AM
Hi,

I've been using the Task Scheduler wrapper and TaskEditDialog in a project - and its mostly working great - thanks for the work on it.

Have an issue that may be caused by my code but I cant get to the bottom of it so far.

My project is a server monitor - we allow the users to set up what to monitor and how to be notified, and then we use your task schedule wrapper and the edit form to allow them to schedule when it will run. On the TaskEditDialog I only show the tabs they need to schedule the task. I also put a guid into the task description which matches the guid of the monitor - so I can do a lookup later on.

Its working great to create a new task, and to fetch the task again to get the last run time etc. But am getting a problem when I go to edit an exiting task using the TaskEditDialog - it crashes when the OK button is pressed, and debugging through your code shows its a null ref exception in the TaskFolder.RegisterTaskDefinition method - if i step into that you can see the v2Folder variable is null, so the code then goes on to try to save it as a v1 task, when it should be v2 and you get a null ref when it tries to get the v1task flags.

Heres some code....
class TaskDemo
{
    //create new task
    public bool ScheduleNewTask(Guid monitorid, string runnerexe, string originalname, Guid scheduleId, out string outname)
    {
        outname = string.Empty;

        using (TaskService ts = new TaskService())
        {
            string arg = monitorid.ToString();

            TaskDefinition td = ts.NewTask();
            td.RegistrationInfo.Description = "Monitoring Task " + scheduleId.ToString();
            var dir = Directory.GetCurrentDirectory();
            td.Actions.Add(new ExecAction(runnerexe, arg, dir));

            TaskEditDialog editorForm = new TaskEditDialog(ts, td, true, true);
            editorForm.TaskName = originalname;
            editorForm.TaskFolder = "Monitoring";
            editorForm.AvailableTabs = AvailableTaskTabs.General | AvailableTaskTabs.Conditions | AvailableTaskTabs.Settings | AvailableTaskTabs.Triggers;

            var res = editorForm.ShowDialog();

            if (res == DialogResult.OK && editorForm.Task != null)
            {
                outname = editorForm.TaskName;
            }

            return res == DialogResult.OK;
        }
    }

    //get a task
    public Task GetTask(Guid scheduleId)
    {
        using (TaskService ts = new TaskService())
        {
            var folder = ts.GetFolder("Monitoring");

            foreach (Task task in folder.Tasks)
            {
                if (task.Definition.RegistrationInfo.Description.Contains(scheduleId.ToString()))
                {
                    return task;
                }
            }
        }

        return null;
    }

    //edit a task
    public bool EditScheduledTask(string runnerexe, string name, Guid scheduleId, out string outname)
    {
        outname = string.Empty;

        var task = GetTask(scheduleId);

        TaskEditDialog editorForm = new TaskEditDialog();
        editorForm.TaskFolder = "Monitoring";
        editorForm.AvailableTabs = AvailableTaskTabs.General | AvailableTaskTabs.Conditions | AvailableTaskTabs.Settings | AvailableTaskTabs.Triggers;
        editorForm.Editable = true;
        editorForm.RegisterTaskOnAccept = true;
        editorForm.Initialize(task);

        var res = editorForm.ShowDialog();

        //!!!!on ok get null reference exception from TaskFolder.RegisterTaskDefinition
        //v2Folder is null so it tries to run through the v1code

        if (res == DialogResult.OK && editorForm.Task != null)
        {
            outname = editorForm.TaskName;
        }

        return res == DialogResult.OK;
    }
}

Is it something wrong with the way I am initializing the TaskEditForm in my edit method? I've tried passing in the task in the constructor, passing in a reference to the task service to editorForm.TaskService and they either have the same result or I end up with an empty form with none of my task details.

Any help would be much appreciated.

Thanks

Andy
Coordinator
Aug 7, 2014 at 10:32 PM
I think the problem is that you are using the 'using' statement in your creation and get methods which close the connection to the system COM server at the end of the 'using' clause. When you call the edit method, you have a valid task object, but the TaskService object is not valid. Opening and closing the TaskService object, is not a good idea in this sample code. I would recommend getting an instance of the TaskService once and holding it until you're done working with the task. In other words, put TaskService into a field variable and don't use the 'using' statements.
Marked as answer by dahall on 8/11/2014 at 7:37 AM
Aug 11, 2014 at 12:52 PM
Hi Dahall,

Apologies for the late reply - just back to work today and have tried your suggestion and it works!

I had assumed the task service instance did not need to be the same one when getting the task and in the edit form - can see where I was incorrect now.

Many thanks for your assistance and work on this project.

Andy