Посты в этой серии:

  1. Список задач для проверки навыков.
  2. Создание задачи таймера.
  3. Использование подходящих классов.
  4. Передача команд задаче таймера (этот пост).
  5. Взаимодействие веб-фронтэнда с задачами таймера.

Задачи таймера сами по себе очень важны для многих решений, но не менее важно взаимодействие задач таймера с другими частями решения.

Например, задача таймера, которая выполняет очистку папок, требует большого количества ресурсов для работы, фактически просмотр всех баз контента для того чтобы удалить папки. Даже если надо удалить ровно одну папку, то задача таймера все равно будет бегать по всей контентной базе данных. Такое поведение крайне расточительно.

Надо как-то ограничить задачу таймера чтобы она бегала только по тем сайтам где разрешит администратор.

Проще всего этого добиться создав фичу уровня Web, которая выставляет свойства узла при активации и модифицировать задачу таймера, чтобы она проверяла свойство.

Код Feature Receiver

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
    SetCleanupFlag(properties, true);
}

public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
    SetCleanupFlag(properties, false);
}

private void SetCleanupFlag(SPFeatureReceiverProperties properties, bool flag)
{
    var web = properties.Feature.Parent as SPWeb;
    web.Properties[Constants.FlagPropertyName] = flag.ToString();
    web.Properties.Update();
}

Изменения в Timer Job:

private void ProcessWeb(SPWeb web)
{
    if (Convert.ToBoolean(web.Properties[Constants.FlagPropertyName]))
    {
        tju.ProcessLists(web.Lists, ProcessList, null);
    }
}

Вот теперь задача таймера будет обрабатывать только то что укажет администратор. Для своих задач передачи данных из контекста веб-приложения в  timer job вы можете также использовать списки, лучше скрытые.

Но если задача таймера запускается нечасто, а результат пользователю нужен в короткое время, то эти способы не подойдут.

WorkItems

Про механизм “очередей” в SharePoint я писал ранее, но тогда не было подходящей задачи для иллюстрации.

Используем простую идею: некоторое действие пользователя ставит в очередь задачу (SPWorkItem), а задача таймера (worker) анализирует очередь на наличие новых задач и обрабатывает их.

Для создания worker необходимо создать класс наследник SPWorkItemJobDefinition, в котором переопределить два метода WorkItemType и ProcessWorkItem. Документация на MSDN утверждает что вам необходимо переопределить один из методов ProcessWorkItems (с буквой s в конце) – не верьте.

При обработке work item есть много тонкостей, но я не буду их тут описывать, а просто использую уже знакомый класс TimerJobUtility, в котором уже сделана вся “грязная” работа.

public class CleaupWorker : SPWorkItemJobDefinition
{
    TimerJobUtility tju;
    WorkItemTimerJobState wiJobState = new WorkItemTimerJobState(true);

    public CleaupWorker() : base() { }

    public CleaupWorker(SPWebApplication webApp)
        : base(Constants.WorkerJobName, webApp)
    {
        this.Title = "Folder cleanup worker";
    }

    public override Guid WorkItemType()
    {
        return Constants.WorkItemType;
    }

    protected override bool ProcessWorkItem(SPContentDatabase contentDatabase, SPWorkItemCollection workItems, SPWorkItem workItem, SPJobState jobState)
    {
        tju = new TimerJobUtility(Constants.TimerJobName, jobState);
        return tju.ProcessWorkItem(workItems, workItem, wiJobState, ProcessWorkItemCore);
    }

    private void ProcessWorkItemCore(SPWorkItem wi, WorkItemTimerJobState timerJobstate)
    {
        var list = timerJobstate.Web.Lists[wi.ParentId];
        CleanupUtility.CleanupList(list);
    }
}

Тем, кто занимается разработкой для SharePoint Foundation повезло гораздо меньше, им придется все подводные камни обходить самостоятельно. Крайне рекомендую для этого посмотреть реализацию TimerJobUtility.

Чтобы поместить WorkItem в очередь необходимо вызывать метод SPSite.AddWorkItem. Остается самый интересный вопрос: где вызывать этот метод. Об этом, и многом другом в следующей статье.

Теги : SharePoint