Verwenden von asynchronen Vorgängen in SharePoint-Add-Ins
Implementieren Sie asynchrone Vorgänge in SharePoint-Add-Ins mithilfe von Microsoft Azure WebJobs.
Gilt für: SharePoint 2013 | SharePoint-Add-Ins | SharePoint Online
Das Core.QueueWebJobUsage-Beispiel zeigt, wie Sie asynchrone Vorgänge mithilfe von vom Anbieter gehosteten Add-Ins und Azure WebJobs in Office 365 erstellen und ausführen.
Verwenden Sie diese Lösung für Folgendes:
Verbessern Sie die Leistung Ihrer Remoteereignisempfänger.
Migrieren Sie zu SharePoint Online, und implementieren Sie die gleiche Zeitgeberauftragsfunktion wie in Ihrer lokalen SharePoint-Umgebung.
Implementieren Sie Zeitintensive Vorgänge, die Sie für Ihre SharePoint-Umgebung ausführen möchten. Zum Beispiel:
AppInstallierte Ereignisse, die länger als das Timeoutintervall von 30 Sekunden ausgeführt werden. Es gibt asynchrone Prozesse in Add-In-Ereignishandlern. Weitere Informationen finden Sie unter Behandeln von Ereignissen in SharePoint-Add-Ins und Erstellen eines Add-In-Ereignisempfängers in SharePoint-Add-Ins.
Benutzerdefinierte Websitesammlungsbereitstellung.
Vorgänge, die Daten zwischen Office 365 und Ihren lokalen Systemen synchronisieren.
Vorgänge, die komplexe Berechnungen ausführen.
Das folgende Diagramm zeigt eine allgemeine Architektur der erforderlichen Komponenten und den Verarbeitungsfluss zwischen diesen Komponenten, wenn ein asynchroner Vorgang ausgeführt wird.
So implementieren Sie asynchrone Vorgänge in Ihrem vom Anbieter gehosteten Add-In mithilfe von Azure WebJobs:
Benutzer führen das in SharePoint Online bereitgestellte Add-In aus.
Das vom Anbieter gehostete Add-In stellt Eingabeparameter bereit, die für den Azure-Webauftrag erforderlich sind, und fügt dann der Azure Storage-Warteschlange eine neue Nachricht hinzu.
Die Azure Storage-Warteschlange löst ein Ereignis in einem fortlaufend ausgeführten Azure WebJob aus, um mit der Verarbeitung der neuen Nachricht zu beginnen.
Der Azure WebJob führt benutzerdefinierte Geschäftslogik für Ihre SharePoint Online-Website aus.
Hinweis
Beim Hinzufügen einer Nachricht zur Azure Storage-Warteschlange wird ein anderer Prozess als der Prozess verwendet, der den Azure-Webjob ausführt. Daher kann Ihr Add-In asynchrone Vorgänge implementieren, indem der Warteschlange mithilfe eines Prozesses neue Nachrichten hinzugefügt werden und dann der Azure WebJob verwendet wird, um diese Nachrichten in einem anderen Prozess zu verarbeiten.
Bevor Sie beginnen
Laden Sie zunächst das Beispiel-Add-In Core.QueueWebJobUsage aus dem Projekt Office 365 Developer patterns and practices auf GitHub herunter, erstellen Sie dann ein Azure-Konto, fügen Sie diesem Konto Details hinzu, und überprüfen Sie, ob Azure WebJob ausgeführt wird.
So erstellen Sie ein Azure Storage-Konto für den Zugriff auf die Azure Storage-Warteschlange:
Melden Sie sich bei Ihrem Microsoft Azure-Portal an.
Wählen Sie New Data Services Storage Quick Create (Neuer>DataServices-Speicher>>– Schnellerstellung) aus.
Geben Sie unter URL Ihren Domänennamen ein. Geben Sie beispielsweise contoso ein.
Wählen Sie unter STANDORT/AFFINITÄTSGRUPPE einen geeigneten Standort aus.
Wählen Sie unter REPLIKATIONdie Option Georedundant aus.
Wählen Sie SPEICHERKONTO ERSTELLEN aus.
So fügen Sie Ihrem neu erstellten Speicherkonto Details hinzu:
Wenn das Azure Storage-Konto erstellt wird, wählen Sie ZUGRIFFSSCHLÜSSEL VERWALTEN aus.
Kopieren Sie unter Zugriffsschlüssel verwalten den SPEICHERKONTONAMEN und DEN PRIMÄREN ZUGRIFFSSCHLÜSSEL.
Wenden Sie die Client-ID, den geheimen Clientschlüssel und Ihre Azure Storage-Kontoinformationen auf mehrere konfigurationsdateien an.
Öffnen Sie unter Hilfsprojekt\Core.QueueWebJobUsage.Console.SendMessage die Datei Program.cs, und geben Sie die URL Ihrer Website in das Feld siteUrl ein.
Legen Sie unter Eigenschaften für Core.QueueWebJobUsage.Job die Option Lokal kopieren für die Verweise Microsoft.SharePoint.Client und Microsoft.SharePoint.Client.Runtime auf True fest. Wenn Sie Lokal kopieren auf True festlegen, werden die Assemblys, auf die verwiesen wird, in Azure kopiert, damit der Azure-WebJob die Verweise auf diese Assemblys auflösen kann.
Stellen Sie den Azure-Webjob bereit. Weitere Informationen finden Sie unter Bereitstellen eines WebJobs-Projekts.
So überprüfen Sie, ob Ihr Azure WebJob ausgeführt wird:
Melden Sie sich bei Ihrem Azure-Portal an.
Wählen Sie Web-Apps und dann die eingegebenen Microsoft Azure-Websites aus.
Wählen Sie WEBJOBS aus.
Vergewissern Sie sich, dass Ihr Azure WebJob in der Liste angezeigt wird und dass SCHEDULE auf Fortlaufend ausgeführt festgelegt ist.
Wählen Sie KONFIGURIEREN aus.
Erstellen Sie in den Add-In-Einstellungen neue Add-In-Einstellungen für ClientId und ClientSecret. Kopieren Sie die Schlüssel-Wert-Paare ClientId und ClientSecret aus der Core.QueueWebJobUsage.Job\app.config-Datei.
Erstellen Sie in Verbindungszeichenfolgen neue Verbindungszeichenfolgen für AzureWebJobsDashboard und AzureWebJobsStorage. Kopieren Sie die Schlüsselpaare AzureWebJobsDashboard und AzureWebJobsStorage (Name) und Wert aus der Core.QueueWebJobUsage.Job\app.config Datei, und legen Sie dann den Typ auf Benutzerdefiniert fest.
Wählen Sie Speichern aus.
Anwenden von Konfigurationseinstellungen
Verwenden Sie die Informationen in der folgenden Tabelle, um Konfigurationseinstellungen auf die Visual Studio-Projektmappe Core.QueueWebJobUsage anzuwenden.
Dateispeicherort | Zu aktualisierende Schlüssel | Zu aktualisierende Wertinformationen |
---|---|---|
Hilfsprogramm Project\Core.QueueWebJobUsage.Console.SendMessage\app.config | StorageConnectionString | Ersetzen Sie [Ihr Kontoname] durch den Speicherkontonamen, der aus dem Azure-Portal kopiert wurde. |
Ersetzen Sie [Ihr Kontoschlüssel] durch den primären Zugriffsschlüssel, der aus dem Azure-Portal kopiert wurde. | ||
Core.QueueWebJobUsageWeb\web.config | StorageConnectionString | Ersetzen Sie [YourAccountName] durch den Namen des Speicherkontos, der aus dem Azure-Portal kopiert wurde. |
Ersetzen Sie [YourAccountKey] durch den primären Zugriffsschlüssel, der aus dem Azure-Portal kopiert wurde. | ||
Core.QueueWebJobUsage.Job\app.config | StorageConnectionString | Ersetzen Sie [YourAccountName] durch den Namen des Speicherkontos, der aus dem Azure-Portal kopiert wurde. |
Ersetzen Sie [YourAccountKey] durch den primären Zugriffsschlüssel, der aus dem Azure-Portal kopiert wurde. | ||
Clientid | Ersetzen Sie [Ihre Add-In-ID] durch die Aus dem Core.QueueWebJobUsageWeb\web.config kopierte Client-ID. | |
ClientSecret | Ersetzen Sie [Ihr Add-In-Geheimnis] durch den geheimen Clientschlüssel, der aus dem Core.QueueWebJobUsageWeb\web.config kopiert wurde. | |
AzureWebJobsDashboard | Ersetzen Sie [YourAccount] durch den Namen des Speicherkontos, der aus dem Azure-Portal kopiert wurde. | |
Ersetzen Sie [YourKey] durch den primären Zugriffsschlüssel, der aus dem Azure-Portal kopiert wurde. | ||
AzureWebJobsStorage | Ersetzen Sie [YourAccount] durch den Namen des Speicherkontos, der aus dem Azure-Portal kopiert wurde. | |
Ersetzen Sie [YourKey] durch den primären Zugriffsschlüssel, der aus dem Azure-Portal kopiert wurde. |
Hinweis
Wenn die ClientId und das ClientSecret in Core.QueueWebJobUsageWeb aktualisiert werden, z. B. wenn Sie die Versionsnummer im AppManifest.xml erhöhen, stellen Sie sicher, dass Sie die ClientId und den ClientSecret im Core.QueueWebJobUsage.Job\app.config aktualisieren.
Verwenden des Core.QueueWebJobUsage-Add-Ins
In der folgenden Tabelle werden alle Visual Studio-Projekte in der Projektmappe Core.QueueWebJobUsage beschrieben.
Visual Studio-Projekt | Beschreibung |
---|---|
Core.QueueWebJobUsage | Ihr SharePoint-Add-In-Projekt. Die folgenden Berechtigungen sind erforderlich:
|
Core.QueueWebJobUsage.Common | Enthält die Geschäftsobjekte und den Geschäftslogikcode – z. B. die Methoden zum Hinzufügen von Nachrichten zur Speicherwarteschlange – für diese Lösung. Dieses Projekt ist enthalten, um Geschäftsobjekte und Geschäftslogik zwischen verschiedenen Projekten gemeinsam zu nutzen. Dies ist in Ihrer Implementierung möglicherweise nicht erforderlich. |
Core.QueueWebJobUsage.Job | Der Azure WebJob, der ausgeführt wird, wenn der Azure Storage-Warteschlange eine neue Nachricht hinzugefügt wird. Dieses Projekt enthält Ihren benutzerdefinierten Geschäftslogikcode. |
Core.QueueWebJobUsageWeb | Das vom Anbieter gehostete Add-In, das die Benutzeroberfläche für das Projekt Core.QueueWebJobUsage enthält. |
Hilfsprojekt\Core.QueueWebJobUsage.Console.SendMessage | Ein Hilfsprojekt, das verwendet werden kann, um die Speicherkontoinformationen und den Erstellungsprozess der Warteschlange zu überprüfen und Nachrichten zur Verarbeitung an die Warteschlange zu senden, ohne die gesamte in diesem Artikel beschriebene Lösung einzurichten. |
Wenn Sie das Codebeispiel Core.QueueWebJobUsage ausführen, wird das vom Anbieter gehostete Add-In angezeigt und zeigt zwei Schaltflächen an: Synchroner Vorgang und Asynchroner Vorgang. Wenn Sie synchrone Vorgänge auswählen, simuliert btnSync_Click in Pages\Default.aspx einen synchronen Prozess mit langer Ausführungsdauer. In diesem Codebeispiel versetzt btnSync_Click den aktuellen Thread für 10 Sekunden in den Ruhezustand und erstellt dann eine Dokumentbibliothek. Wenn Sie asynchronen Vorgang auswählen, führt btnAsync_Click in Pages\Default.aspx Folgendes aus:
Ruft den aktuellen Benutzer ab.
Erstellt ein SiteModifyRequest-Geschäftsobjekt , das die Daten speichert, die in die Nachricht eingeschlossen werden sollen, die an die Azure Storage-Warteschlange gesendet wird. In diesem Codebeispiel enthalten die gesendeten Daten den Namen des aktuellen Benutzers und die URL der aktuellen Website.
Ruft SiteManager() auf. AddAsyncOperationRequestToQueue , um die Nachricht der Azure Storage-Warteschlange hinzuzufügen.
Hinweis
Der Code in diesem Artikel wird wie besehen und ohne jegliche Garantie zur Verfügung gestellt, gleich ob ausdrücklich oder konkludent, einschließlich jedweder stillschweigenden Gewährleistung der Eignung für einen bestimmten Zweck, Marktgängigkeit oder Nichtverletzung von Rechten.
protected void btnAsync_Click(object sender, EventArgs e)
{
var spContext = SharePointContextProvider.Current.GetSharePointContext(Context);
using (var clientContext = spContext.CreateUserClientContextForSPHost())
{
// Get the current user.
var currUser = clientContext.Web.CurrentUser;
clientContext.Load(currUser);
clientContext.ExecuteQuery();
// Create business object, and then add the request to the queue.
SiteModifyRequest request = new SiteModifyRequest() { RequestorName = currUser.Title, SiteUrl = Page.Request["SPHostUrl"] };
new SiteManager().AddAsyncOperationRequestToQueue(request,
ConfigurationManager.AppSettings["StorageConnectionString"]);
processViews.ActiveViewIndex = 1;
lblStatus.Text = "Asynchronous operation to create document library started.";
}
}
In Core.QueueWebJobUsage.Common in SiteManager.cs führt AddAsyncOperationRequestToQueue folgende Aktionen aus:
Erstellt ein CloudStorageAccount-Objekt mithilfe der AccountName - und AccountKey-Konfigurationsinformationen in der Core.QueueWebJobUsageWeb\web.config-Datei.
Erstellt mithilfe von CloudStorageAccount.CreateCloudQueueClient einen Azure Storage-Warteschlangenclient.
Verwendet CloudQueueClient.GetQueueReference , um einen Verweis auf die Azure Storage-Warteschlange abzurufen, deren Name dem Wert der SiteManager.StorageQueueName-Konstante entspricht.
Verwendet CloudQueue.CreateIfNotExists , um die Azure Storage-Warteschlange zu erstellen, wenn sie nicht vorhanden ist.
Verwendet CloudQueue.AddMessage , um der Azure Storage-Warteschlange eine neue Nachricht hinzuzufügen. Das modifyRequest-Geschäftsobjekt wird in ein CloudQueueMessage-Objekt serialisiert, das der Azure Storage-Warteschlange hinzugefügt wird.
public void AddAsyncOperationRequestToQueue(SiteModifyRequest modifyRequest,
string storageConnectionString)
{
CloudStorageAccount storageAccount =
CloudStorageAccount.Parse(storageConnectionString);
// Get queue or create a new one if one does not exist.
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
CloudQueue queue = queueClient.GetQueueReference(SiteManager.StorageQueueName);
queue.CreateIfNotExists();
// Add a message to queue.
queue.AddMessage(new CloudQueueMessage(JsonConvert.SerializeObject(modifyRequest)));
}
Nachdem die Nachricht der Azure Storage-Warteschlange hinzugefügt wurde, wartet ein kontinuierlich ausgeführter Azure WebJob auf die neue Nachricht und verarbeitet sie dann. Der Azure-Webjob ist in Core.QueueWebJobUsage.Job definiert. Wenn der Azure-WebJob ausgeführt wird, erstellt Main in Core.QueueWebJobUsage.Job\Program.cs einen neuen JobHost und ruft dann RunAndBlock auf. JobHost koordiniert Aufrufe von Methoden, die mit dem QueueTrigger-Attribut gekennzeichnet sind, und überwacht Nachrichten in einer bestimmten Warteschlange. RunAndBlock stellt sicher, dass der Azure WebJob kontinuierlich ausgeführt wird, und ruft ProcessQueueMessage auf. Dies ist die Methode, die ausgelöst wird, wenn der Azure Storage-Warteschlange eine neue Nachricht hinzugefügt wird. Das Azure WebJobs SDK ordnet den HauptthreadProcessQueueMessage zu. Weitere Informationen finden Sie unter Erstellen eines .NET-Webjobs im Azure-Add-In-Dienst.
static void Main()
{
var host = new JobHost();
// The following code ensures that the WebJob will run continuously.
host.RunAndBlock();
}
ProcessQueueMessage verarbeitet neue Nachrichten, die der Azure Storage-Warteschlange hinzugefügt werden, wie folgt:
Verwenden Sie das QueueTrigger-Attribut , um anzugeben, dass ProcessQueueMessage ausgelöst werden soll, wenn eine neue Nachricht in die Warteschlange geschrieben wird, deren Name dem Wert siteManager.StorageQueueName entspricht.
Schreiben in das Protokoll für den Azure WebJob mithilfe der Protokollvariablen , die als Parameter an ProcessQueueMessage übergeben wurde.
Aufruf von SiteManager(). Führen Sie SiteModification aus, um einen geschäftsintensiven Prozess auf der Website auszuführen. In diesem Codebeispiel wird der Thread für 10 Sekunden in den Ruhezustand versetzt, und dann wird eine Dokumentbibliothek erstellt.
public static void ProcessQueueMessage(
[QueueTrigger(SiteManager.StorageQueueName)]
SiteModifyRequest modifyRequest, TextWriter log)
{
log.WriteLine(string.Format("{0} '{1}' {2} '{3}'.",
"Received new site modification request with URL",
modifyRequest.SiteUrl,
"from person named as ",
modifyRequest.RequestorName));
try
{
Uri targetSite = new Uri(modifyRequest.SiteUrl);
// Get the realm for the URL.
string realm = TokenHelper.GetRealmFromTargetUrl(targetSite);
// Get the access token for the URL.
// Requires this add-in to be registered with the tenant.
string accessToken = TokenHelper.GetAppOnlyAccessToken(
TokenHelper.SharePointPrincipal,
targetSite.Authority, realm).AccessToken;
// Get client context with access token.
using (var ctx =
TokenHelper.GetClientContextWithAccessToken(
targetSite.ToString(), accessToken))
{
// Call business logic code.
new SiteManager().PerformSiteModification(ctx, modifyRequest);
}
}
catch (Exception ex)
{
log.WriteLine(string.Format("Site modification to URL {0} failed with following details.", modifyRequest.SiteUrl));
log.WriteLine(ex.ToString());
throw;
}
}