Infrastructure de travail du minuteur PnP
Le cours Infrastructure de travail du minuteur PnP est conçu pour simplifier la création de processus d’arrière-plan qui fonctionnent sur les sites SharePoint. L’infrastructure du travail du timer est similaire aux travaux du timer de code de confiance totale locaux (SPJobDefinition). La principale différence entre l’infrastructure du travail du timer et le travail du travail du timer code de confiance totale est que l’infrastructure de travail du travail du timer utilise uniquement les API côté client et par conséquent peut (et doit) être exécuté en dehors de SharePoint. L’infrastructure de travail du timer permet de créer des travaux du timer qui fonctionnent SharePoint Online.
Une fois qu’un travail du timer a été créé, il doit être programmé et exécuté. Les deux options les plus courantes sont :
- Lorsque Microsoft Azure est la plateforme d’hébergement, les travaux du timer peuvent être déployés et exécutés en tant que tâches web Azure.
- Lorsque Windows Server est la plateforme d’hébergement (par exemple, pour les SharePoint locaux), les travaux du Windows scheduler peuvent être déployés et exécutés.
Pour une présentation vidéo des travaux du timer, voir la vidéo Introduction à l’infrastructure de travail du timer PnP,qui présente l’infrastructure de travail du timer et illustre l’exemple de travail du travail du timer simple.
Exemple de travail du timer simple
Dans cette section, vous allez apprendre à créer un travail du temps très simple. L’objectif de cet exemple est de fournir au lecteur une vue rapide . Plus loin, nous fournirons une explication plus détaillée de l’infrastructure du travail du temps.
Notes
Pour obtenir une solution PnP plus complète avec dix exemples de travaux individuels du minuteur, des exemples « Hello World » aux travaux d’expiration de contenu réels, voir Core.TimerJobs.Samples.
Les étapes suivantes décrivent comment créer un travail du timer simple.
Étape 1 : Créer un projet console et référencer PnP Core
Créez un projet de type « console » et référencez la bibliothèque principale PnP en faisant l’une des choses suivantes :
Ajoutez le package Office 365 pratiques et modèles de développement principaux NuGet votre projet. Il existe un package NuGet pour v15 (local) et pour v16 (Office 365). Il s’agit de l’option recommandée.
Ajoutez le projet source principal PnP existant à votre projet. Cela vous permet d’entrer pas à pas dans le code principal PnP lors du débogage.
Notes
Vous serez responsable de la mise à jour de ce code avec les dernières modifications ajoutées à PnP.
Étape 2 : Créer une classe de travail du timer et ajouter votre logique de travail du travail du timer
Ajoutez une classe pour le travail du timer nommé SimpleJob.
Faire hériter la classe TimerJob de la classe de base abstraite.
Dans le constructeur, donnez un nom ( ) au travail du temps et connectez le handler d’événement
base("SimpleJob")TimerJobRun.Ajoutez votre logique de travail du temps au handler d’événements TimerJobRun.
Le résultat sera similaire à ce qui suit :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SharePoint.Client;
using OfficeDevPnP.Core.Framework.TimerJobs;
namespace Core.TimerJobs.Samples.SimpleJob
{
public class SimpleJob: TimerJob
{
public SimpleJob() : base("SimpleJob")
{
TimerJobRun += SimpleJob_TimerJobRun;
}
void SimpleJob_TimerJobRun(object sender, TimerJobRunEventArgs e)
{
e.WebClientContext.Load(e.WebClientContext.Web, p => p.Title);
e.WebClientContext.ExecuteQueryRetry();
Console.WriteLine("Site {0} has title {1}", e.Url, e.WebClientContext.Web.Title);
}
}
}
Étape 3 : Mettre à jour program.cs pour utiliser le travail du timer
Le travail du timer créé à l’étape précédente doit encore être exécuté. Pour ce faire, mettez à jour Program.cs en suivant les étapes suivantes :
Inssérez votre classe de travail du timer.
Fournissez les détails d’authentification pour le travail du timer. Cet exemple utilise le nom d’utilisateur et le mot de passe pour s’authentifier SharePoint Online.
Ajoutez un ou plusieurs sites pour le programme de travail du temps d’accès. Cet exemple utilise un caractère de caractères wild card dans l’URL. Le travail du timer s’exécute sur tous les sites qui correspondent à cette URL de caractères malveillants.
Démarrez le travail du timer en appelant la méthode Run.
static void Main(string[] args)
{
// Instantiate the timer job class
SimpleJob simpleJob = new SimpleJob();
// The provided credentials need access to the site collections you want to use
simpleJob.UseOffice365Authentication("user@tenant.onmicrosoft.com", "pwd");
// Add one or more sites to operate on
simpleJob.AddSite("https://<tenant>.sharepoint.com/sites/d*");
// Run the job
simpleJob.Run();
}
Options de déploiement de travail du temps
L’étape précédente illustre un travail du timer simple. L’étape suivante consiste à déployer le travail du timer.
Un travail du temps est un fichier .exe qui doit être programmé sur une plateforme d’hébergement. Selon la plateforme d’hébergement choisie, le déploiement diffère. Les sections suivantes décrivent les deux options de plateforme d’hébergement les plus courantes :
- Utilisation d’Azure comme plateforme d’hébergement.
- Utilisation Windows Server comme plateforme d’hébergement.
Déployer des travaux du timer dans Azure à l’aide d’Azure WebJobs
Avant de déployer un travail du temps, assurez-vous que le travail peut s’exécuter sans intervention de l’utilisateur. L’exemple de cet article invite l’utilisateur à fournir un mot de passe ou une question secrète client (voir plus d’informations dans la section Authentification), qui fonctionne pendant le test, mais ne fonctionne pas lors du déploiement. Les exemples existants permettent tous à l’utilisateur de fournir un mot de passe ou une secret client à l’aide app.config fichier :
<appSettings>
<add key="user" value="user@tenant.onmicrosoft.com"/>
<add key="password" value="your password goes here!"/>
<add key="domain" value="Contoso"/>
<add key="clientid" value="a4cdf20c-3385-4664-8302-5eab57ee6f14"/>
<add key="clientsecret" value="your clientsecret goes here!"/>
</appSettings>
Une fois ces modifications ajoutées au fichier app.config, exécutez le travail du Visual Studio pour confirmer qu’il s’exécute sans intervention de l’utilisateur.
Le déploiement réel vers Azure est basé sur Azure WebJobs. Pour déployer cet exemple de travail du temps, suivez les étapes suivantes :
Cliquez avec le bouton droit sur le projet Visual Studio puis choisissez Publier en tant que WebJob Azure.
Fournissez une planification pour le travail du timer, puis choisissez OK.
Choisissez Microsoft Azure sites web en tant que cible de publication. Vous serez invité à vous inscrire à Azure et à sélectionner le site web Azure qui hébergera le travail du temps (vous pouvez également en créer un si nécessaire).
Choose Publish to push the WebJob to Azure.
Une fois que le travail du timer a été publié, vous pouvez déclencher le travail et vérifier l’exécution du travail à partir de Visual Studio ou du portail Azure.

En outre, le travail du timer peut être exécuté à partir du nouveau portail Azure en sélectionnant le travail et en sélectionnant Exécuter. Pour plus d’informations sur l’application WebJobs à partir du nouveau portail, voir l’article « Exécuter des tâches en arrière-plan avec WebJobs dans Azure App Service».

Notes
Pour obtenir des instructions détaillées sur le déploiement d’une webjob Azure, voir La mise en place d’Azure WebJobs (travaux du timer)pour vos sites Office 365 sites.
Déployer des travaux du Windows Server à l’aide du Windows Scheduler
Lorsqu’il est déployé sur Windows Server, le travail du timer doit s’exécuter sans intervention de l’utilisateur.
Modifiez le fichier app.config comme décrit dans la section précédente Déployer des travaux du timer sur Azure à l’aide d’Azure WebJobs.
Copiez la version finale de votre travail sur le serveur sur qui vous souhaitez l’exécuter.
Important
Copiez tous les assemblys appropriés, le fichier .exe et le fichier .config pour vous assurer que le travail peut s’exécuter sur le serveur sans installer de fichiers ou de programmes supplémentaires sur le serveur.
Planifier l’exécution du travail du timer. Nous vous recommandons d’utiliser le Windows de planification des tâches. Pour utiliser le Windows de tâches :
- Ouvrez le Programmeur des tâches (Programmeur des tâches > du Panneau de contrôle).
- Choisissez Créer une tâche et spécifiez un nom et un compte qui exécutera la tâche.
- Choisissez Déclencheurs et ajoutez un nouveau déclencheur. Spécifiez la planification que vous souhaitez pour le travail du timer.
- Choose Actions and choose the action Start a program, select the timer job .exe file, and then set the start in folder.
- Choisissez OK pour enregistrer la tâche.

Infrastructure de travail du timer en profondeur
Cette section détaille les fonctionnalités de l’infrastructure de travail du tempsur et leur fonctionnement.
Structure
La classe TimerJob est une classe de base abstraite qui contient les propriétés publiques, méthodes et événements suivants :

La plupart des propriétés et méthodes sont expliquées plus en détail dans les sections à venir. Les autres propriétés et méthodes sont décrites ici :
- Propriété IsRunning : obtient une valeur indiquant si le travail du timer est en cours d’exécution. Valeur true en cas d’exécution ; false si ce n’est pas le cas.
- Propriété Name : obtient le nom du travail du temps. Le nom est initialement définie dans le constructeur du travail du timer.
- Propriété SharePointVersion : obtient ou définit la SharePoint version. Cette propriété est automatiquement définie en fonction de la version de la Microsoft.SharePoint.Client.dll chargée et ne doit généralement pas changer. Vous pouvez toutefois modifier cette propriété au cas où vous souhaitez utiliser les bibliothèques CSOM v16 dans un déploiement v15 (local).
- Propriété version : obtient la version de ce travail du temps. La version est initialement définie dans le constructeur de travail du temps ou est définie par défaut sur 1.0 lorsqu’elle n’est pas définie via le constructeur.
Pour préparer l’exécuter, vous devez d’abord le configurer :
- Fournir des paramètres d’authentification.
- Fournissez une étendue, qui est une liste de sites.
- Définissez éventuellement les propriétés du travail du temps.
Du point de vue de l’exécution, les étapes globales suivantes sont prises lors du début de l’exécution d’un travail du timer :
- Résoudre les sites: les URL de sites avec caractères wild card (par exemple, ) sont résolues en une liste
https://tenant.sharepoint.com/sites/d*réelle de sites existants. Si l’extension du sous-site a été demandée, la liste des sites résolus est étendue avec tous les sous-sites. - Créez des lots de travail en fonction des paramètres actuels et créez un thread par lot.
- Les threads exécutent des lots de travail et appellent l’événement TimerJobRun pour chaque site de la liste.
Pour plus d’informations sur chaque étape, voir les sections suivantes.
Authentification
Avant d’utiliser un travail du timer, il doit savoir comment s’authentifier à nouveau SharePoint. L’infrastructure prend actuellement en charge les approches dans l’enum AuthenticationType : Office365, NetworkCredentials et AppOnly. L’utilisation des méthodes suivantes définit également automatiquement la propriété AuthenticationType sur la valeur appropriée d’Office365, NetworkCredentials et AppOnly.
L’exemple de flux suivant montre les étapes à suivre, suivies d’explications détaillées de chaque approche.

Informations d’identification de l’utilisateur
Pour spécifier les informations d’identification de l’utilisateur à Office 365, vous pouvez utiliser les deux méthodes ci-après :
public void UseOffice365Authentication(string userUPN, string password)
public void UseOffice365Authentication(string credentialName)
La première méthode accepte un nom d’utilisateur et un mot de passe. La seconde vous permet de spécifier des informations d’identification génériques stockées dans Windows d’informations d’identification. La capture d’écran suivante montre les bertonline informations d’identification génériques. Pour l’utiliser pour authentifier le travail du temps, fournissez le paramètre bertonline de la deuxième méthode.

Il existe des méthodes similaires pour l’exécution SharePoint sur site:
public void UseNetworkCredentialsAuthentication(string samAccountName, string password, string domain)
public void UseNetworkCredentialsAuthentication(string credentialName)
Application uniquement
L’authentification d’application uniquement est la méthode préférée, car vous pouvez accorder des autorisations d’étendue client. Pour les informations d’identification de l’utilisateur, le compte d’utilisateur doit avoir les autorisations nécessaires.
Notes
Certaines logiques de résolution de site ne fonctionnent pas avec l’authentification d’application uniquement. Pour plus d’informations, voir la section suivante.
Pour configurer le travail d’authentification d’application uniquement, utilisez l’une des méthodes suivantes :
public void UseAppOnlyAuthentication(string clientId, string clientSecret)
public void UseAzureADAppOnlyAuthentication(string clientId, string clientSecret)
La même méthode peut être utilisée pour l’environnement local Office 365 ou SharePoint, ce qui facilite le transport entre les environnements des travaux du timer qui utilisent l’authentification d’application uniquement.
Notes
Lorsque vous utilisez l’authentification d’application uniquement, la logique de votre travail du timer échoue lorsque des API qui ne fonctionnent pas avec AuthenticationType.AppOnly sont utilisées. Les exemples classiques sont l’API de recherche, l’écriture dans le magasin de taxonomie et l’utilisation de l’API de profil utilisateur.
Sites à utiliser
Lorsqu’un travail du timer s’exécute, un ou plusieurs sites doivent être exécutés.
Ajouter des sites à un travail du timer
Pour ajouter des sites à un travail du temps, utilisez l’ensemble de méthodes suivant :
public void AddSite(string site)
public void ClearAddedSites()
Pour ajouter un site, spécifiez une URL complète (par exemple) ou une https://tenant.sharepoint.com/sites/dev URL de caractères wild card.
Une URL de caractères wild card est une URL qui se termine par un astérisque ( * ). Une seule est autorisée et il doit s’agit * du dernier caractère de l’URL. Un exemple d’URL de caractères wild card est , qui renvoie toutes https://tenant.sharepoint.com/sites/* les collections de sites sous le chemin d’accès géré de ce site. Pour un autre exemple, https://tenant.sharepoint.com/sites/dev* renvoie toutes les collections de sites où l’URL contient dev .
En règle générale, les sites sont ajoutés par le programme qui ins instantie l’objet de travail du temps, mais si nécessaire, le travail du timer peut prendre le contrôle sur la liste des sites transmis. Pour ce faire, ajoutez une substitution de méthode pour la méthode virtuelle, comme UpdateAddedSites illustré dans l’exemple suivant :
public override List<string> UpdateAddedSites(List<string> addedSites)
{
// Let's assume we're not happy with the provided list of sites, so first clear it
addedSites.Clear();
// Manually adding a new wildcard Url, without an added URL the timer job will do...nothing
addedSites.Add("https://bertonline.sharepoint.com/sites/d*");
// Return the updated list of sites
return addedSites;
}
Spécifier les informations d’identification d’une éumération
Après l’ajout d’une URL de caractères wild card et la définition de l’authentification sur l’application uniquement, spécifiez les informations d’identification d’éumération. Les informations d’identification d’énumération sont utilisées pour récupérer une liste de collections de sites utilisées dans l’algorithme de correspondance de site pour renvoyer une liste réelle de sites.
Pour obtenir la liste des collections de sites, l’infrastructure du Office 365 (v16) et l’infrastructure du système local (v15) se comporte différemment :
- Office 365: la méthode Tenant.GetSiteProperties est utilisée pour lire les collections de sites « normales » ; L’API de recherche est utilisée pour lire les collections OneDrive Entreprise sites.
- SharePoint local: l’API de recherche est utilisée pour lire toutes les collections de sites.
Étant donné que l’API de recherche ne fonctionne pas avec un contexte utilisateur, le travail du temps revient aux informations d’identification d’éumération spécifiées.
Pour spécifier les informations d’identification de l’utilisateur à Office 365, vous pouvez utiliser les deux méthodes ci-après :
public void SetEnumerationCredentials(string userUPN, string password)
public void SetEnumerationCredentials(string credentialName)
Il existe des méthodes similaires pour l’exécution SharePoint sur site:
public void SetEnumerationCredentials(string samAccountName, string password, string domain)
public void SetEnumerationCredentials(string credentialName)
La première méthode accepte simplement un nom d’utilisateur, un mot de passe et éventuellement un domaine (en local). La seconde spécifie les informations d’identification génériques stockées dans le gestionnaire d Windows d’informations d’identification. Consultez la section Authentification pour en savoir plus sur le Gestionnaire d’informations d’identification.
Développement de sous-site
Souvent, vous souhaitez que le code de travail du travail du timer soit exécuté sur le site racine de la collection de sites et sur tous les sous-sites de cette collection de sites. Pour ce faire, définissez la propriété ExpandSubSites sur true. Ainsi, le travail du timer développe les sous-sites dans le cadre de l’étape de résolution du site.
Remplacer les sites résolus et/ou développés
Une fois que l’infrastructure du temps a résolu les sites de caractères wild card et éventuellement développé les sous-sites, l’étape suivante consiste à traiter la liste des sites. Avant de traiter la liste des sites, vous pouvez modifier la liste des sites. Par exemple, vous pouvez supprimer des sites spécifiques ou ajouter d’autres sites à la liste. Pour ce faire, vous pouvez utiliser la méthode virtuelle ResolveAddedSites. L’exemple suivant montre comment remplacer la méthode ResolveAddedSites pour supprimer un site de la liste.
public override List<string> ResolveAddedSites(List<string> addedSites)
{
// Use default TimerJob base class site resolving
addedSites = base.ResolveAddedSites(addedSites);
//Delete the first one from the list...simple change. A real life case could be reading the site scope
//from a SQL (Azure) DB to prevent the whole site resolving.
addedSites.RemoveAt(0);
//Return the updated list of resolved sites...this list will be processed by the timer job
return addedSites;
}
Événement TimerJobRun
L’infrastructure du travail du timer fractionne la liste des sites en lots de travail. Chaque lot de sites est exécuté sur son propre thread. Par défaut, l’infrastructure crée cinq lots et cinq threads pour exécuter ces cinq lots. Consultez la section Threading pour en savoir plus sur les options de thread de travail du timer.
Lorsqu’un thread traite un lot, l’événement TimerJobRun est déclenché par l’infrastructure du timer et fournit toutes les informations nécessaires à l’exécuter. Les travaux du timer sont exécutés en tant qu’événements, de sorte que le code doit connecter un handler d’événements à l’événement TimerJobRun :
public SimpleJob() : base("SimpleJob")
{
TimerJobRun += SimpleJob_TimerJobRun;
}
void SimpleJob_TimerJobRun(object sender, TimerJobRunEventArgs e)
{
// your timer job logic goes here
}
Une autre approche consiste à utiliser un délégué en ligne comme illustré ici :
public SimpleJob() : base("SimpleJob")
{
// Inline delegate
TimerJobRun += delegate(object sender, TimerJobRunEventArgs e)
{
// your timer job logic goes here
};
}
Lorsque l’événement TimerJobRun se déclenche, vous recevez un objet TimerJobRunEventArgs, qui fournit les informations nécessaires pour écrire la logique du travail du temps. Les attributs et méthodes suivants sont disponibles dans cette classe :

Plusieurs des propriétés et toutes les méthodes sont utilisées dans la fonctionnalité de gestion d’état facultative, qui est abordée dans la section suivante. Toutefois, les propriétés suivantes sont toujours disponibles dans chaque événement, quelle que soit la configuration utilisée :
- Propriété d’URL : obtient ou définit l’URL du site pour le travail du temps d’activité. Il peut s’agit du site racine de la collection de sites, mais il peut également s’agit d’un sous-site au cas où l’extension du site serait effectuée.
- Propriété ConfigurationData : obtient ou définit des données de configuration supplémentaires du travail du temps (facultatif). Ces données de configuration sont transmises dans le cadre de l’objet TimerJobRunEventArgs.
- Propriété WebClientContext : obtient ou définit l’objet ClientContext pour l’URL actuelle. Cette propriété est un objet ClientContext pour le site défini dans la propriété Url. Il s’agit généralement de l’objet ClientContext que vous utiliseriez dans le code de votre travail du temps.
- Propriété SiteClientContext : obtient ou définit l’objet ClientContext pour le site racine de la collection de sites. Cette propriété permet d’accéder au site racine si le travail du timer en a besoin. Par exemple, le travail du timer peut ajouter une mise en page à la galerie de pages maîtres à l’aide de la propriété SiteClientContext.
- Propriété TenantClientContext : obtient ou définit l’objet ClientContext pour qu’il fonctionne avec l’API client. Cette propriété fournit un objet ClientContext construit à l’aide de l’URL du site d’administration du client. Pour utiliser l’API client dans le handler d’événement TimerJobRun du travail du temps, créez un objet Tenant à l’aide de cette propriété TenantClientContext.
Tous les objets ClientContext utilisent les informations d’authentification décrites dans la section Authentification. Si vous avez choisi d’utiliser les informations d’identification de l’utilisateur, assurez-vous que le compte utilisé dispose des autorisations nécessaires pour fonctionner sur les sites spécifiés. Lorsque vous utilisez l’application uniquement, il est préférable de définir des autorisations d’étendue client sur le principal d’application uniquement.
Gestion de l’état
Lorsque vous écrivez une logique de travail du temps, vous devez souvent persister l’état ; par exemple, pour enregistrer la dernière fois qu’un site a été traitée ou pour stocker des données pour prendre en charge la logique métier de votre travail du timer. Pour cette raison, l’infrastructure de travail du travail du temps dispose de fonctionnalités de gestion d’état.
La gestion de l’état stocke et récupère un ensemble de propriétés standard et personnalisées en tant que chaîne sérialisée JSON dans le sac des propriétés web du site traitée (nom = nom du travail du temps + « _Properties »). Voici les propriétés par défaut de l’objet TimerJobRunEventArgs :
- Propriété PreviousRun : obtient ou définit la date et l’heure de l’utilisation précédente.
- Propriété PreviousRunSuccessful : obtient ou définit une valeur indiquant si l’opération précédente a réussi. Notez que l’auteur du travail du timer est chargé de signaler qu’un travail s’exécute comme réussi en définition de la propriété CurrentRunSuccessful dans le cadre de l’implémentation de votre travail du temps.
- Propriété PreviousRunVersion : obtient ou définit la version du travail du timer de l’utilisation précédente.
En plus de ces propriétés standard, vous avez également la possibilité de spécifier vos propres propriétés en ajoutant des paires de valeurs de mots clés à la collection Properties de l’objet – TimerJobRunEventArgs. Pour faciliter cette tâche, il existe trois méthodes pour vous aider :
- SetProperty ajoute ou met à jour une propriété.
- GetProperty renvoie la valeur d’une propriété.
- DeleteProperty supprime une propriété de la collection de propriétés.
Le code suivant montre comment utiliser la gestion d’état :
void SiteGovernanceJob_TimerJobRun(object o, TimerJobRunEventArgs e)
{
try
{
string library = "";
// Get the number of admins
var admins = e.WebClientContext.Web.GetAdministrators();
Log.Info("SiteGovernanceJob", "ThreadID = {2} | Site {0} has {1} administrators.", e.Url, admins.Count, Thread.CurrentThread.ManagedThreadId);
// grab reference to list
library = "SiteAssets";
List list = e.WebClientContext.Web.GetListByUrl(library);
if (!e.GetProperty("ScriptFileVersion").Equals("1.0", StringComparison.InvariantCultureIgnoreCase))
{
if (list == null)
{
// grab reference to list
library = "Style%20Library";
list = e.WebClientContext.Web.GetListByUrl(library);
}
if (list != null)
{
// upload js file to list
list.RootFolder.UploadFile("sitegovernance.js", "sitegovernance.js", true);
e.SetProperty("ScriptFileVersion", "1.0");
}
}
if (admins.Count < 2)
{
// Oops, we need at least 2 site collection administrators
e.WebClientContext.Site.AddJsLink(SiteGovernanceJobKey, BuildJavaScriptUrl(e.Url, library));
Console.WriteLine("Site {0} marked as incompliant!", e.Url);
e.SetProperty("SiteCompliant", "false");
}
else
{
// We're all good...let's remove the notification
e.WebClientContext.Site.DeleteJsLink(SiteGovernanceJobKey);
Console.WriteLine("Site {0} is compliant", e.Url);
e.SetProperty("SiteCompliant", "true");
}
e.CurrentRunSuccessful = true;
e.DeleteProperty("LastError");
}
catch(Exception ex)
{
e.CurrentRunSuccessful = false;
e.SetProperty("LastError", ex.Message);
}
}
L’état est stocké en tant que propriété Sérialisée JSON unique, ce qui signifie qu’il peut également être utilisé par d’autres personnalisations. Par exemple, si le travail du timer a écrit l’entrée d’état « SiteCompliant=false », une routine JavaScript peut inviter l’utilisateur à agir car le travail du timer a déterminé que le site était conforme.
Threading
L’infrastructure du travail du timer utilise par défaut des threads pour paralléliser le travail. Le threading est utilisé à la fois pour l’extension du sous-site (sur demande) et pour l’exécution de la logique réelle du travail du temps (événement TimerJobRun) pour chaque site. Les propriétés suivantes peuvent être utilisées pour contrôler l’implémentation de threads :
- Propriété UseThreading : obtient ou définit une valeur indiquant si le thread est utilisé. Par défaut est vrai. Définir sur False pour effectuer toutes les actions à l’aide du thread d’application principal.
- Propriété MaximumThreads : obtient ou définit le nombre de threads à utiliser pour ce travail du minuteur. Les valeurs valides sont de 2 à 100. La valeur par défaut est 5. Avoir un grand nombre de threads n’est pas nécessairement plus rapide que d’avoir seulement quelques threads. Le nombre optimal doit être obtenu via des tests à l’aide d’une variété de nombres de threads. La valeur par défaut de 5 threads a été trouvée pour améliorer considérablement les performances dans la plupart des scénarios.
Limitation
Étant donné qu’un travail du temps utilise des opérations de thread et de travail du temps sont généralement des opérations qui consomment beaucoup de ressources, une opération de travail du timer peut être limitée. Pour gérer correctement la limitation, l’infrastructure du travail du timer et l’ensemble de PnP Core utilisent la méthode ExecuteQueryRetry au lieu de la méthode ExecuteQuery par défaut.
Notes
Il est important d’utiliser ExecuteQueryRetry dans le code d’implémentation de votre travail du timer.
Problèmes decurrency : traiter tous les sous-sites d’une collection de sites dans le même thread
Les travaux du timer peuvent avoir des problèmes de concurrence lors de l’utilisation de plusieurs threads pour traiter des sous-sites.
Prenons cet exemple : le thread A traite le premier ensemble de sous-sites de la collection de sites 1 et le thread B traite le reste des sous-sites de la collection de sites 1. Si le travail du temps traite le sous-site et le site racine (à l’aide de l’objet SiteClientContext), il peut y avoir un problème d’concurrence car le thread A et le thread B traitent le site racine.
Pour éviter le problème de concurrence (sans l’exécution des travaux du timer dans un thread unique), utilisez la méthode GetAllSubSites dans le travail du timer.
Le code suivant montre comment utiliser la méthode GetAllSubSites dans un travail du temps :
public class SiteCollectionScopedJob: TimerJob
{
public SiteCollectionScopedJob() : base("SiteCollectionScopedJob")
{
// ExpandSites *must* be false as we'll deal with that at TimerJobEvent level
ExpandSubSites = false;
TimerJobRun += SiteCollectionScopedJob_TimerJobRun;
}
void SiteCollectionScopedJob_TimerJobRun(object sender, TimerJobRunEventArgs e)
{
// Get all the subsites in the site we're processing
IEnumerable<string> expandedSites = GetAllSubSites(e.SiteClientContext.Site);
// Manually iterate over the content
foreach (string site in expandedSites)
{
// Clone the existing ClientContext for the sub web
using (ClientContext ccWeb = e.SiteClientContext.Clone(site))
{
// Here's the timer job logic, but now a single site collection is handled in a single thread which
// allows for further optimization or prevents race conditions
ccWeb.Load(ccWeb.Web, s => s.Title);
ccWeb.ExecuteQueryRetry();
Console.WriteLine("Here: {0} - {1}", site, ccWeb.Web.Title);
}
}
}
}
Logging
L’infrastructure de travail du timer utilise les composants de journalisation principale PnP, car elle fait partie de la bibliothèque principale PnP. Pour activer la journalisation principale PnP intégrée, configurez-la à l’aide du fichier de configuration approprié (app.config ou web.config). L’exemple suivant illustre la syntaxe requise :
<system.diagnostics>
<trace autoflush="true" indentsize="4">
<listeners>
<add name="DebugListenter" type="System.Diagnostics.TextWriterTraceListener" initializeData="trace.log" />
<!--<add name="consoleListener" type="System.Diagnostics.ConsoleTraceListener" />-->
</listeners>
</trace>
</system.diagnostics>
À l’aide du fichier de configuration ci-dessus, l’infrastructure du travail du temps utilise la structure pour écrire des journaux dans un fichier appelé trace.log dans le même dossier que le travail du System.Diagnostics.TextWriterTraceListener .exe. D’autres écouteurs de suivi sont disponibles, tels que :
- ConsoleTraceListener écrit les journaux dans la console.
- La méthode décrite dans Diagnostics cloud - Prendre le contrôle dela journalisation et du suivi dans Windows Azure . Cette méthode utilise Microsoft.WindowsAzure.Diagnostics. DiagnosticMonitorTraceListener. Des ressources Azure supplémentaires sont disponibles ici :
Nous vous conseillons vivement d’utiliser la même approche de journalisation pour votre code de travail du travail du timer personnalisé que pour l’infrastructure de travail du timer. Dans le code de votre travail du timer, vous pouvez utiliser la classe PnP Core Log :
void SiteGovernanceJob_TimerJobRun(object o, TimerJobRunEventArgs e)
{
try
{
string library = "";
// Get the number of admins
var admins = e.WebClientContext.Web.GetAdministrators();
Log.Info("SiteGovernanceJob", "ThreadID = {2} | Site {0} has {1} administrators.", e.Url, admins.Count, Thread.CurrentThread.ManagedThreadId);
// Additional timer job logic...
e.CurrentRunSuccessful = true;
e.DeleteProperty("LastError");
}
catch(Exception ex)
{
Log.Error("SiteGovernanceJob", "Error while processing site {0}. Error = {1}", e.Url, ex.Message);
e.CurrentRunSuccessful = false;
e.SetProperty("LastError", ex.Message);
}
}