Создание списка в ListAdded List Event Receiver

Я пытаюсь программно создать список календарей в SharePoint 2010 всякий раз, когда определенный список создается с помощью решения для песочницы. Я реализовал ListAdded ListEventReceiver, чтобы запустить код для создания календаря.

public class GenerateCalendar : SPListEventReceiver
{
   public override void ListAdded(SPListEventProperties properties)
   {
      base.ListAdded(properties);

      // Exit out if this is not a MyList type
      if(!IsMyList(properties))
         return;

      string calendarTitle = properties.List.Title + " Calendar";

      SPWeb spWeb = properties.Web;
      SPListTemplateType type = new SPListTemplateType();
      type = SPListTemplateType.Events;

      // Execution breaks here:
      Guid listGuid = spWeb.Lists.Add(calendarTitle, "Associated Calendar", type);
      SPList newList = spWeb.Lists[listGuid];
      newList.OnQuickLaunch = properties.List.OnQuickLaunch;
      newList.Update();
   }
}

Когда я вызываю spWeb.Lists.Add (...), я получаю исключение SPException (запрошенное выполнение изолированного кода было отклонено, поскольку служба хоста изолированного кода была слишком занята для обработки запроса.)

Из документации MSDN я вижу, что метод SPListCollection.Add доступен в изолированных решениях (https://msdn.microsoft.com/en-us/library/office/ms413986(v=office.14).aspx ). Есть ли ограничение на создание такого списка в этом приемнике событий? Кто-нибудь знает, почему это не работает?

Отредактировано для добавления созданных файлов Feature.xml и Elements.xml.

Feature.xml:

<?xml version="1.0" encoding="utf-8"?>
<Feature xmlns="http://schemas.microsoft.com/sharepoint/"
   Title="Calendar Generator"
   Description="Generates a calendar"
   Id="dfe3388c-c063-4873-a41b-5c066907c510"
   Scope="Web">
   <ElementManifests>
      <ElementManifest Location="GenerateCalendar\Elements.xml" />
   </ElementManifests>
</Feature>

Elements.xml

<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   <Receivers >
      <Receiver>
         <Name>GenerateCalendarListAdding</Name>
         <Type>ListAdding</Type>
         <Assembly>MyListGenerator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5cff2198a602ec41</Assembly>
         <Class>MyListGenerator.Event_Receivers.GenerateCalendar.GenerateCalendar</Class>
         <SequenceNumber>10000</SequenceNumber>
      </Receiver>
      <Receiver>
         <Name>GenerateCalendarListDeleting</Name>
         <Assembly>MyListGenerator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5cff2198a602ec41</Assembly>
         <Class>MyListGenerator.Event_Receivers.GenerateCalendar.GenerateCalendar</Class>
         <SequenceNumber>10000</SequenceNumber>
      </Receiver>
      <Receiver>
         <Name>GenerateCalendarListAdded</Name>
         <Type>ListAdded</Type>
         <Assembly>MyListGenerator, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5cff2198a602ec41</Assembly>
         <Class>MyListGenerator.Event_Receivers.GenerateCalendar.GenerateCalendar</Class>
         <SequenceNumber>10000</SequenceNumber>
      </Receiver>
   </Receivers>
</Elements>

person Ricardo Reyna    schedule 26.04.2016    source источник


Ответы (2)


Я нашел ответ. Очевидно, создание списка в этом приемнике событий вызывало рекурсивный вызов приемника событий, хотя у меня была проверка для выхода из списков, не основанных на шаблоне MyList. Решением было просто добавить EventFiringEnabled = false.

...
SPWeb spWeb = properties.Web;
SPListTemplateType type = new SPListTemplateType();
type = SPListTemplateType.Events;

EventFiringEnabled = false;  // Disable event firing and create the list
Guid listGuid = spWeb.Lists.Add(calendarTitle, "Associated Calendar", type);
SPList newList = spWeb.Lists[listGuid];
newList.OnQuickLaunch = properties.List.OnQuickLaunch;
newList.Update();
EventFiringEnabled = true;  // Re-enable event firing
...
person Ricardo Reyna    schedule 27.04.2016

Вы можете создавать приемники событий, которые являются производными от SPListEventReceiver в изолированном решении. Однако приемник событий должен быть зарегистрирован декларативно в вашем файле элементов функции; его нельзя зарегистрировать с помощью объектной модели (например, через приемник функций).

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

Кроме того, если ваша среда работает особенно медленно, служба пользовательского кода будет перезапущена, если ее ограничение по времени (по умолчанию 30 секунд) будет превышено во время одного запроса.

Дополнительную информацию см. В разделе Общие сведения о мониторинге решений в документации Изолированные решения от Microsoft: https://msdn.microsoft.com/en-us/library/ff798382.aspx

Соответствующие выдержки приведены ниже.

Очки ресурсов:

Если решения в семействе сайтов превышают ежедневное выделение точек ресурсов для этого семейства сайтов, SharePoint переведет каждое изолированное решение в семействе сайтов в автономный режим до конца дня.

Точки ресурсов вычисляются в соответствии с 14 различными измерениями, известными как меры ресурсов, включая время выполнения ЦП, потребление памяти и необработанные исключения.

...

SharePoint учитывает наиболее дорогостоящую меру ресурса в качестве общей суммы для решения, а не суммы всех мер.

Абсолютные пределы:

Чтобы предотвратить нестабильность решений, находящихся в изолированной программной среде, SharePoint также отслеживает отдельные изолированные решения для каждого запроса. Каждая из 14 показателей ресурсов включает свойство AbsoluteLimit, которое определяет жесткое ограничение ресурсов, которые изолированное решение может потреблять в одном запросе. Если абсолютный предел превышен, SharePoint завершает запрос, останавливая и перезапуская рабочий процесс песочницы. Например, мера ресурса времени выполнения ЦП имеет абсолютный предел по умолчанию в 60 секунд. Если для выполнения одного запроса требуется более 60 секунд, служба пользовательского кода остановит и перезапустит рабочий процесс песочницы, выполняющий запрос.

WorkerProcessExecutionTimeout:

Кроме того, служба пользовательского кода включает свойство WorkerProcessExecutionTimeout со значением по умолчанию 30 секунд. Если этот временной предел превышен во время одного запроса, служба пользовательского кода перезапустит рассматриваемый домен приложения, и запрос вернет ошибку.

person Thriggle    schedule 26.04.2016
comment
Похоже, что это не так. Приемник событий регистрируется декларативно. Я позволил Visual Studio справиться с этим, но я проверил сгенерированные Feature.xml и Elements.xml в соответствии с примером в документации, которую вы связали, и он довольно хорошо совпадает (за исключением отсутствия атрибута ListTemplateId в теге Receivers элементов .xml). Отредактировал свой вопрос и добавил вывод файлов в конец. - person Ricardo Reyna; 27.04.2016
comment
Что касается WorkerProcessExecutionTimeout, я тестировал его несколько раз, чтобы увидеть, сколько времени требуется, прежде чем я получу исключение, и это постоянно составляло около 10 секунд. Я проверил значение WorkerProcessExecutionTimeout (установлено на 30) через PowerShell и даже попытался изменить его на 60, но это не имело значения. Исключение происходит всего через 10 секунд. Использование ресурсов составляет около 0,07 (хотя это число, кажется, колеблется от 0 до 0,15). Есть ли другие идеи относительно того, что может быть причиной этого? - person Ricardo Reyna; 27.04.2016