SafeDispatcher gebruiken voor aangepaste gehoste besturingselementen in Unified Service Desk

 

Is van toepassing op: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2013, Dynamics CRM 2015, Dynamics CRM 2016

Unified Service Desk is een op Windows Presentation Foundation (WPF) gebaseerde toepassing waarbij alle bewerkingen in Unified Service Desk in de belangrijkste WPF Dispatcher-thread worden uitgevoerd. De WPF Dispatcher-klasse biedt services voor het beheren van de wachtrij met werkitems voor een thread.

U kunt Unified Service Desk uitbreiden door aangepaste besturingselementen te maken en te hosten binnen Unified Service Desk. Als u echter een aangepast gehost besturingselement hebt dat foutieve code bevat of bewerkingen uitvoert met nieuwe threads zonder uitzonderingen tijdens code-uitvoering te verwerken, kan het tot stabiliteitsproblemen in Unified Service Desk leiden en kan de clienttoepassing zelfs vastlopen of niet meer reageren. De niet-verwerkte uitzonderingen in aangepaste besturingselementen van derden maken het moeilijk het probleem te identificeren en op te lossen voor het product-/ondersteuningsteam, aangezien zij mogelijk geen toegang hebben tot de informatie waarom een fout/uitzondering is opgetreden in Unified Service Desk en tot de exacte code die de fout heeft veroorzaakt.

SafeDispatcher biedt een krachtig en informatief mechanisme voor de verwerking van uitzonderingen voor aangepaste gehoste besturingselementen in Unified Service Desk doordat kant-en-klare logboekregistratie wordt verschaft voor niet-verwerkte uitzonderingen, met gedetailleerde informatie over de bron en oorzaak van de uitzondering. U kunt de afhandeling van uitzonderingen door SafeDispatcher configureren en overschrijven om bepaalde andere stappen uit te voeren. Dit voorkomt ook dat de Unified Service Desk-client niet reageert vanwege niet-verwerkte uitzonderingen in de code van het aangepaste gehoste besturingselement.

Notitie

Deze functie is geïntroduceerd in Unified Service Desk 2.2.1.

In dit onderwerp

Wat is SafeDispatcher?

Hoe gebruikt u SafeDispatcher?

Migratie van WPF Dispatcher naar SafeDispatcher in bestaande aangepaste gehoste besturingselementen

Punten om rekening mee te houden bij het gebruik van SafeDispatcher

Wat is SafeDispatcher?

SafeDispatcher is op dezelfde wijze ontwikkeld als WPF Dispatcher en biedt veerkrachtige en informatieve verwerking van uitzonderingen voor aangepaste gehoste besturingselementen binnen Unified Service Desk Het wordt beschikbaar gesteld als beveiligde eigenschap, SafeDispatcher, in de klasse DynamicsBaseHostedControl, wat SafeDispatcher automatisch beschikbaar maakt voor alle Unified Service Desk aangepaste gehoste besturingselementen die zijn afgeleid van de DynamicsBaseHostedControl-klasse.

Notitie

Gebruik niet de klasse SafeDispatcher in uw code om met SafeDispatcher te werken. In plaats daarvan moet u de eigenschap SafeDispatcher in het exemplaar van uw aangepaste gehoste besturingselement, die is afgeleid van de klasse DynamicsBaseHostedControl, gebruiken om SafeDispatcher te gebruiken.

Net als WPF Dispatcher biedt SafeDispatcher methoden zoals BeginInvoke, Invoke en InvokeAsync om bewerkingen synchroon of asynchroon uit te voeren op SafeDispatcher, met een aanvullende Boole-parameter, runOnMainUiThread, die bepaalt of SafeDispatcher wordt uitgevoerd in de UI-thread.

SafeDispatcher heeft de volgende voordelen:

  • Beveiligde UI Dispatcher-thread: ontwikkelaars kunnen alle UI-afhankelijke bewerkingen uitvoeren op SafeDispatcher door de parameter runOnMainUiThread in te stellen op "true" in de aanroepmethode om de SafeDispatcher in de UI-thread uit te voeren. Eventuele niet-verwerkte uitzonderingen die optreden in de hoofd-UI-dispatcher, worden veilig afgehandeld op het niveau van het gehoste besturingselement, in plaats van omhoog te gaan naar de algemene DispatcherUnhandledException-gebeurtenishandler.

  • Beveiligde niet-UI Dispatcher-thread: ontwikkelaars kunnen alle UI-onafhankelijke code op SafeDispatcher uitvoeren. door de parameter runOnMainUiThread op "false" in te stellen in de aanroepende methode om de SafeDispatcher uit te voeren op de niet-UI thread. Eventuele niet-verwerkte uitzonderingen die optreden in de hoofd-niet-UI-dispatcher, worden veilig afgehandeld op het niveau van het gehoste besturingselement, in plaats van omhoog te gaan naar de algemene DispatcherUnhandledException-gebeurtenishandler.

  • Gedetailleerde informatie over bron en oorzaak van de uitzondering:: de SafeDispatcher-uitzonderingshandler wordt geactiveerd wanneer een niet-verwerkte uitzondering op het niveau van de DynamicsBaseHostedControl optreedt door de UI- of niet-UI-thread, die Unified Service Desk toestaat kritieke informatie vast te leggen op het niveau van het gehoste besturingselement, zoals de naam van het gehoste besturingselement, het type gehost besturingselement, de methodenaam en de complete stacktracering om de exacte locatie en oorzaak van de uitzondering te bepalen.

  • De SafeDispatcher-uitzonderingsafhandeling configureren of overschrijven: ontwikkelaars kunnen gebruikmaken van de kant-en-klare werking van de SafeDispatcher-uitzonderingshandler om de gebruiker informatie te geven over de niet-verwerkte uitzondering of de werking overschrijven op basis van hun bedrijfsvereiste, zoals aanvullende logboekregistratie configureren, op sessies gebaseerde besturingselementen sluiten of de Unified Service Desk-client sluiten.

Hoe gebruikt u SafeDispatcher?

De eigenschap SafeDispatcher is beschikbaar voor alle exemplaren van Unified Service Desk aangepaste gehoste besturingselementen die zijn afgeleid van de DynamicsBaseHostedControl-klasse. Een SafeDispatcher-exemplaar wordt beschikbaar om op de UI-thread uit te voeren wanneer het aangepaste gehoste besturingselement wordt geïnitialiseerd. Een SafeDispatcher-exemplaar is echter alleen beschikbaar om te worden uitgevoerd op een niet-UI-thread wanneer u de aanroepmethode voor de eerste keer uitvoert.

  • Een UI-specifieke functie synchroon aanroepen met SafeDispatcher

    SafeDispatcher.Invoke(() =>
                {
                    ProcessData();
                }, DispatcherPriority.Normal, CancellationToken.None, true);
    

    OR

    SafeDispatcher.Invoke(() =>
                {
                    ProcessData();
                }, DispatcherPriority.Normal, CancellationToken.None);
    

    Notitie

    Voor UI-specifieke functies moet u de optionele parameter runOnMainUiThread instellen op "waar". Als u geen waarde opgeeft voor deze parameter, wordt standaard "waar" doorgegeven. Elk van de bovenstaande methodedefinities werkt dus goed.

  • Een UI-specifieke functie asynchroon aanroepen met SafeDispatcher. U kunt de methode BeginInvoke of InvokeAsync gebruiken.

    SafeDispatcher.BeginInvoke(new Action(() =>
                {
                   ProcessData();
                }));
    

    OR

    SafeDispatcher.InvokeAsync(new Action(() =>
                {
                   ProcessData();
                }));
    

De SafeDispatcher-uitzonderingshandler aanpassen

Met de introductie van SafeDispatcher activeren alle niet-verwerkte uitzonderingen in Unified Service Desk de SafeDispatcherUnhandledException Event in plaats van de algemene DispatcherUnhandledException-gebeurtenis. De SafeDispatcherUnhandledExceptionHandler Method biedt een kant-en-klare uitzonderingshandler voor SafeDispatcher om informatie aan de Unified Service Desk-gebruiker weer te geven met de volgende details: bronbesturingselement waar de uitzondering is opgetreden en gedetailleerde informatie over de uitzondering.

U kunt de kant-en-klare uitzonderingsafhandeling voor SafeDispatcher ook overschrijven om andere bewerkingen uit te voeren zoals de gebruiker vragen een op een sessie gebaseerd niet-dynamisch gehost besturingselement te sluiten.

In de volgende voorbeeldcode ziet u hoe u de kant-en-klare uitzonderingshandler van SafeDispatcher kunt overschrijven om een berichtvenster weer te geven om de gebruiker te vragen het aangepaste gehoste besturingselement te sluiten wanneer een uitzondering optreedt:

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); });
    }
}

Migratie van WPF Dispatcher naar SafeDispatcher in bestaande aangepaste gehoste besturingselementen

Aangezien het contract tussen WPF Dispatcher en SafeDispatcher vrijwel identiek is, is de inspanning om te verplaatsen van WPF Dispatcher naar SafeDispatcher minimaal. Als u een exemplaar van een gehost besturingselement dat is afgeleid van de klasse DynamicsBaseHostedControl, wilt migreren, vervangt u alle Dispatcher-exemplaren door SafeDispatcher.

Neem bijvoorbeeld de volgende code:

Dispatcher.Invoke((System.Action)delegate()
{
    DynamicsLogger.Logger.Log("Raising SetupHotKey's", TraceEventType.Verbose);
    SetupHotkeys();
    CRMGlobalManager.AppWithFocusChanged += CRMGlobalManager_AppWithFocusChanged;
    FireEvent("DesktopReady");
    InitializeFocusSelection();
});

Vervang Dispatcher in de bovenstaande code door SafeDispatcher; de rest van de code blijft hetzelfde:

SafeDispatcher.Invoke((System.Action)delegate()
{
    DynamicsLogger.Logger.Log("Raising SetupHotKey's", TraceEventType.Verbose);
    SetupHotkeys();
    CRMGlobalManager.AppWithFocusChanged += CRMGlobalManager_AppWithFocusChanged;
    FireEvent("DesktopReady");
    InitializeFocusSelection();
});

Punten om rekening mee te houden bij het gebruik van SafeDispatcher

SafeDispatcher biedt een multithreaded model aan dat grote voordelen heeft bij het synchroon of asynchroon verzenden van functies naar UI- of niet-UI-threads. Bewerkingen die moeten worden uitgevoerd op threads die beschikbaar zijn met fouttolerantie, moeten worden uitgevoerd op SafeDispatcher. Multi-threading moet echter zeer zorgvuldig worden geïmplementeerd om impasses tussen threads te vermijden. Eén zo'n voorbeeld is synchrone verzending van een niet-UI-thread naar de hoofd-WPF Dispatcher. Neem dit voorbeeld:

Thread thread = new Thread(() =>
{
    Dispatcher.Invoke(ProcessData);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Priority = ThreadPriority.Highest;
thread.IsBackground = true;
thread.Start();
thread.Join();

De thread.Join()-methode veroorzaakt dat de hoofdthread wordt geblokkeerd tijdens het wachten op beëindiging vaneen Single-Threaded Apartment-thread (STA), maar de STA-thread wacht tot de hoofdthread de uitvoering van ProcessData voltooit. Dit veroorzaakt een impasse in uw app.

Kijk ook naar het volgende voorbeeld:

// Invoke on STA thread
SafeDispatcher.Invoke(() =>
{
    // Invoke back on main dispatcher
    SafeDispatcher.Invoke(() =>
    {
        ProcessData();
    });
}, false);

De SafeDispatcherUnhandledExceptionHandler Method wordt aangeroepen als een uitzondering optreedt in de WPF Dispatcher of in de STA niet-UI-thread en wordt geactiveerd in de respectieve thread waar de uitzondering is opgetreden. U moet oppassen dat u de bovenstaande combinatie niet in deze handler plaatst. Als de uitzondering is opgetreden in een niet-UI-thread, moet u dus niet synchroon verzenden naar de hoofd-UI-dispatcher.

protected override void SafeDispatcherUnhandledExceptionHandler(object sender, SafeDispatcherUnhandledExceptionEventArgs ex)
{
    Dispatcher.Invoke(LogException);                    // Incorrect
    SafeDispatcher.Invoke(LogException);            // Incorrect
    SafeDispatcher.BeginInvoke(LogException);  // Correct
    SafeDispatcher.InvokeAsync(LogException); // Correct
}

Zie ook

Analyse: een aangepast gehost besturingselement voor Unified Service Desk maken
Volledige servicedesk uitbreiden
TechNet: Diagnostische registratie van client configureren in Unified Service Desk

Unified Service Desk 2.0

© 2017 Microsoft. Alle rechten voorbehouden. Auteursrecht