Verwendung SafeDispatcher für die benutzerdefinierte Steuerelemente in Unified Service Desk
Gilt für: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2013, Dynamics CRM 2015, Dynamics CRM 2016
Unified Service Desk ist eine Windows Presentation Foundation (WPF)-basierte Anwendung in der alle Vorgänge in Unified Service Desk über den Haupt-WPF Dispatcher-Thread ausgeführt werden. Die WPF Dispatcher-Klasse stellt Services für die Verwaltung von Warteschlange Arbeitselementen für einen Thread bereit.
Sie können Unified Service Desk erweitern, indem Sie benutzerdefinierte Steuerelemente erstellen und in Unified Service Desk hosten. Wenn ein benutzerdefiniertes gehostetes Steuerelement fehlerhaften Code enthält oder fehlerhafte Vorgänge führt einen neuen Threads verwendet ohne Ausnahmen zu behandeln kann während des Ausführung Fehler in Unified Service Desk auftreten und es kann möglicherweise zu Stabilitätsproblemen für die Clientanwendung mit Einfrieren kommen. Die nicht behandelten Ausnahmen von benutzerdefinierten Steuerelementen von Drittanbietern erschwert die Problemlösung durch das Produkt/Supportteam. Dieses hat möglicherweise keinen Zugriff auf die Informationen, wenn ein Fehler in Unified Service Desk aufgetreten ist, und den genauen Code, der den Fehler verursacht.
Der SafeDispatcher bietet eine leistungsfähige und und sichere Ausnahmebehandlung für benutzerdefinierte Steuerelemente in Unified Service Desk über vordefinierte Protokollierung für nicht verarbeitete Ausnahmen mit Informationen zur Ursache und die Ursache der Ausnahme. Er erlaubt die Konfiguration oder Überschreibung der SafeDispatcher-Ausnahmebehandlung, um einige weitere Schritte auszuführen. Dies verhindert auch, das der Unified Service Desk - Client nicht mehr reagiert weil nicht behandelten Ausnahmen in benutzerdefiniertem Code in gehosteten Steuerelementen auftreten.
Hinweis
Diese Funktion wurde eingeführt in Unified Service Desk 2.2.1 eingeführt.
In diesem Thema
Was ist SafeDispatcher?
So verwenden Sie SafeDispatcher
Migrieren von WPF Dispatcher zu SafeDispatcher in vorhandenen benutzerdefinierten gehosteten Steuerelementen
Zu berücksichtigende Punkte beim Verwenden von SafeDispatcher
Was ist SafeDispatcher?
SafeDispatcher basiert auf demselben Code wie der WPF Dispatcher und bietet eine sichere und informative Ausnahmebehandlung für die benutzerdefinierten Steuerelemente in Unified Service Desk. Dies wird als geschützte Eigenschaft SafeDispatcher der DynamicsBaseHostedControl-Klasse verfügbar gemacht, die SafeDispatcher automatisch für alle benutzerdefinierten gehosteten Unified Service Desk Steuerelemente verfügbar macht, die von der DynamicsBaseHostedControl-Klasse abgeleitet werden.
Hinweis
Verwenden Sie die SafeDispatcher-Klasse nicht in Ihrem Code, um mit SafeDispatcher zu arbeiten. Stattdessen müssen Sie die SafeDispatcher-Eigenschaft in der benutzerdefinierten Instanz des gehosteten Steuerelements verwenden, die von der DynamicsBaseHostedControl-Klasse abgeleitet wird, um SafeDispatcher zu verwenden.
Wie bei WPF Dispatcher stellt SafeDispatcher Methoden wie BeginInvoke, Invoke und InvokeAsync bereit, um Ausführungsvorgänge synchron oder asynchron in SafeDispatcher mit einem weiteren booleschen Parameter (runOnMainUiThread) auszuführen, der bestimmt, ob SafeDispatcher im UI-Thread oder nicht ausgeführt wird.
SafeDispatcher bietet die folgenden Vorteile:
Geschützter UI Dispatcher Thread: Entwickler können alle UI-abhängigen Vorgänge auf SafeDispatcher ausführen, indem sie den runOnMainUiThread Parameter auf "true" in der Invoke-Methode zum Ausführen von SafeDispatcher im UI-Thread festlegen. Jede nicht verarbeitete Ausnahme, die für den Haupt-UI-Dispatcher ausgelöst wird, wird sicher auf der Ebene des gehosteten Steuerelements verarbeitet statt vom globalen Handler DispatcherUnhandledExceptions-Ereignis.
Geschützter Nicht-UI-Dispatcher-Thread: Entwickler können alle UI-unabhängigen Code auf SafeDispatcher ausführen. mithilfe des runOnMainUiThread-Parameters auf "false" in der Invoke-Methode zum ausführen des SafeDispatcher Nicht-UI Threads. Jede nicht verarbeitete Ausnahme, die für den Nicht-UI-Dispatcher ausgelöst wird, wird sicher auf der Ebene des gehosteten Steuerelements verarbeitet statt vom globalen Handler DispatcherUnhandledExceptions-Ereignis.
Ausführliche Informationen zum Ausnahmequelle und -ursachen:: Der SafeDispatcher Ausnahmehandler wird ausgelöst, wenn eine nicht verarbeitete Ausnahme auf DynamicsBaseHostedControl Ebene durch einen UI- oder Nicht-UI-Thread ausgelöst wird. Dies erlaubt Unified Service Desk das Erfassen von wichtigen Informationen auf der Ebene des Steuerelements (Name, Typ, Methodenname und Stack), um die genauen Ursache der Ausnahme zu identifizieren.
Konfigurieren oder überschreiben von SafeDispatcher-Ausnahmehandler: Entwickler können das Verhalten des SafeDispatcher-Ausnahmehandlers vordefiniert nutzen, um den Benutzer Informationen zur nicht verarbeitete Ausnahme anzuzeigen, oder das Verhalten gemäß der geschäftlichen Anforderung überschreiben und eine zusätzliche Protokollierung zu konfigurieren oder den Unified Service Desk Client zu beenden.
So verwenden Sie SafeDispatcher
Die SafeDispatcher-Eigenschaft ist für alle benutzerdefinierten Instanzen von gehosteten Steuerelementen für Unified Service Desk verfügbar, die von der DynamicsBaseHostedControl-Klasse abgeleitet werden. Eine SafeDispatcher-Instanz ist verfügbar, um über den UI-Thread ausgeführt zu werden, wenn das benutzerdefinierte gehostete Steuerelement initialisiert wird. Eine SafeDispatcher-Instanz nur verfügbar, um über den Nicht-UI-Thread auszuführen, wenn Sie die Invoke-Methode zum ersten mal ausführen.
Eine UI-spezifische Funktion über den SafeDispatcher synchron aufrufen
SafeDispatcher.Invoke(() => { ProcessData(); }, DispatcherPriority.Normal, CancellationToken.None, true);
ODER
SafeDispatcher.Invoke(() => { ProcessData(); }, DispatcherPriority.Normal, CancellationToken.None);
Hinweis
Für UI-Funktionen sollten Sie den optionalen Parameter runOnMainUiThread auf "True" festlegen. Wird dieser Wert nicht angegeben, wird der Standard "True" verwendet. Jeder oben angegebenen Methodendefinition funktioniert.
Eine UI-spezifische Funktion über den SafeDispatcher asynchron aufrufen Sie können die Methode BeginInvoke oder InvokeAsync verwenden.
SafeDispatcher.BeginInvoke(new Action(() => { ProcessData(); }));
ODER
SafeDispatcher.InvokeAsync(new Action(() => { ProcessData(); }));
Anpassen der SafeDispatcher-Ausnahmehandler
mit der Einführung von SafeDispatcher löschen alle nicht behandelten Ausnahmen in Unified Service Desk den SafeDispatcherUnhandledException Event anstelle des globalen DispatcherUnhandledExceptions-Ereignis aus.SafeDispatcherUnhandledExceptionHandler Method stellt einen vordefinierten Ausnahmehandler für den SafeDispatcher zur Anzeige von Informationen für den Unified Service Desk-Benutzer mit den folgenden Informationen bereit: Quellsteuerelement, wo eine Ausnahme aufgetreten ist und ausführliche Informationen zur Ausnahme.
Sie können die Ausnahmebehandlung auch überschreiben, um SafeDispatcher andere Vorgänge wie eine Benachrichtigung des Benutzers zum Schließen eines sitzungsbasierten dynamisches gehosteten Steuerelements zu informieren.
Der folgende Beispielcode veranschaulicht, wie Sie den vordefinierten SafeDispatcher-Ausnahmehandler überschreiben, um ein Meldungsfeld anzuzeigen, um den Benutzer zum Schließen des gehosteten benutzerdefinierten Steuerelement aufzufordern.
protected override void SafeDispatcherUnhandledExceptionHandler(object sender, SafeDispatcherUnhandledExceptionEventArgs ex)
{
string error = String.Format(CultureInfo.InvariantCulture,
"Error in hosted control Application:{0} - Exception : {1} \r\nInnerException\r\n {2}", this.ApplicationName, ex.Exception, ex.InnerException);
DynamicsLogger.Logger.Log(error, TraceEventType.Error);
if (MessageBox.Show("Exception occurred in hosted control - " + this.ApplicationName + ".Do you wish to close it ?", "Question", MessageBoxButton.YesNo,
MessageBoxImage.Warning) == MessageBoxResult.Yes)
{
SafeDispatcher.BeginInvoke(() => { this.desktopAccess.CloseDynamicApplication(this.ApplicationName); });
}
}
Migrieren von WPF Dispatcher zu SafeDispatcher in vorhandenen benutzerdefinierten gehosteten Steuerelementen
Da WPF Dispatcher und SafeDispatcher fast identisch sind, ist Aufwand beim Migrieren minimal. Für jede Instanz des gehosteten Steuerelements, das von der DynamicsBaseHostedControl-Klasse abgeleitet wird, ersetzen Sie alle "Dispatcher" Instanzen durch "SafeDispatcher".
Stellen Sie sich beispielsweise den folgende Code vor:
Dispatcher.Invoke((System.Action)delegate()
{
DynamicsLogger.Logger.Log("Raising SetupHotKey's", TraceEventType.Verbose);
SetupHotkeys();
CRMGlobalManager.AppWithFocusChanged += CRMGlobalManager_AppWithFocusChanged;
FireEvent("DesktopReady");
InitializeFocusSelection();
});
Ersetzen Sie Dispatcher oben im Code durch SafeDispatcher; Der Rest des Codes bleibt unverändert:
SafeDispatcher.Invoke((System.Action)delegate()
{
DynamicsLogger.Logger.Log("Raising SetupHotKey's", TraceEventType.Verbose);
SetupHotkeys();
CRMGlobalManager.AppWithFocusChanged += CRMGlobalManager_AppWithFocusChanged;
FireEvent("DesktopReady");
InitializeFocusSelection();
});
Zu berücksichtigende Punkte beim Verwenden von SafeDispatcher
SafeDispatcher bietet ein Multithread-Modell, das Funktionen effizient synchron und asynchron auf die UI- und Nicht-UI-Threads verteilt. Vorgänge, die über Threads ausgeführt werden müssen, die über eine Fehlertoleranz verfügen, sollten über SafeDispatcher ausgeführt werden. Allerdings sollte Multithreading sehr sorgfältig implementiert werden, um Deadlocks zwischen Threads zu vermeiden. Ein Beispiel ist das synchrone Dispatchen von Nicht-UI-Threads über den Haupt-WPF-Dispatcher. Sehen Sie sich dieses Beispiel an:
Thread thread = new Thread(() =>
{
Dispatcher.Invoke(ProcessData);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Priority = ThreadPriority.Highest;
thread.IsBackground = true;
thread.Start();
thread.Join();
Die thread.Join()-Methode blockiert den Hauptthread und wartet auf die Beendigung eines STA- Threads (single-threaded apartment). Der STA-Thread wartet jedoch auf den Hauptthread, um die Ausführung von ProcessData zu beenden. Die führt zu einer Deadlocksituation.
Stellen Sie sich den folgende Code vor:
// Invoke on STA thread
SafeDispatcher.Invoke(() =>
{
// Invoke back on main dispatcher
SafeDispatcher.Invoke(() =>
{
ProcessData();
});
}, false);
Der SafeDispatcherUnhandledExceptionHandler Method wird bei einer Ausnahme im WPF-Dispatcher oder im STA-Nicht-UI-Thread aufgerufen und wird für den entsprechenden Thread ausgelöst, für den die Ausnahme auftritt. Sie sollten darauf achten, keine der obrigen Kombination zu verwenden (Ausnahme tritt in Nicht-UI-Thread auf, wird jedoch nicht synchron zum Haupt-UI-Dispatcher verteilt).
protected override void SafeDispatcherUnhandledExceptionHandler(object sender, SafeDispatcherUnhandledExceptionEventArgs ex)
{
Dispatcher.Invoke(LogException); // Incorrect
SafeDispatcher.Invoke(LogException); // Incorrect
SafeDispatcher.BeginInvoke(LogException); // Correct
SafeDispatcher.InvokeAsync(LogException); // Correct
}
Siehe auch
Exemplarische Vorgehensweise: Erstellen eines benutzerdefinierten gehosteten Steuerelements für Unified Service Desk
Unified Service Desk erweitern
TechNet: Konfigurieren von Client-Diagnoseprotokollierungen in Unified Service Desk
Unified Service Desk 2.0
© 2017 Microsoft. Alle Rechte vorbehalten. Copyright