Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Si applica a: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2013, Dynamics CRM 2015, Dynamics CRM 2016
Unified Service Desk è un'applicazione basata su Windows Presentation Foundation (WPF) nella quale tutte le operazioni in Unified Service Desk vengono eseguite nel thread principale WPF Dispatcher. La classe WPF Dispatcher offre servizi per la gestione della coda degli elementi di lavoro per un thread.
Puoi estendere Unified Service Desk creando controlli personalizzati e ospitandoli in Unified Service Desk. Tuttavia, se un controllo ospitato personalizzato contiene codice in errore o esegue operazioni utilizzando nuovi thread senza una gestione appropriata delle eccezioni durante l'esecuzione del codice, possono verificarsi problemi di stabilità in Unified Service Desk e potrebbe inoltre provocare che l'applicazione client si blocchi o non risponda. Le eccezioni non gestite nei controlli personalizzati di terze parti rendono difficile l'identificazione e la risoluzione del problema per il team di supporto o del prodotto in quanto non può accedere alle informazioni sul perché si è verificato un errore o un'eccezione in Unified Service Desk e al codice esatto che ha causato l'errore.
SafeDispatcher offre un meccanismo di gestione delle eccezioni informativo ed efficace per i controlli ospitati personalizzati in Unified Service Desk fornendo la registrazione predefinita delle eccezioni non gestite con informazioni dettagliate sull'origine e sulla causa dell'eccezione e permettendoti di configurare o sovrascrivere la gestione delle eccezioni SafeDispatcher per eseguire eventuali altre operazioni. In tal modo si impedisce al client Unified Service Desk di non rispondere a causa delle eccezioni non gestite nel codice del controllo ospitato personalizzato.
Nota
Questa funzione è stata introdotta in Unified Service Desk 2.2.1.
In questo argomento
Che cos'è SafeDispatcher?
Come utilizzare SafeDispatcher?
Migrazione da WPF Dispatcher a SafeDispatcher in controlli ospitati personalizzati esistenti
Elementi da considerare quando si utilizza SafeDispatcher
Che cos'è SafeDispatcher?
SafeDispatcher è progettato sulle stesse linee di WPF Dispatcher e offre una gestione delle eccezioni resiliente e informativa per i controlli ospitati personalizzati in Unified Service Desk. È esposto come proprietà protetta, SafeDispatcher, nella classe DynamicsBaseHostedControl, che rende disponibile SafeDispatcher automaticamente per tutti i controlli ospitati personalizzati Unified Service Desk che derivano dalla classe DynamicsBaseHostedControl.
Nota
Non usare la classe SafeDispatcher nel codice per utilizzare SafeDispatcher. In questo caso, devi utilizzare la proprietà SafeDispatcher nell'istanza di tipo controllo ospitato personalizzato derivato dalla classe DynamicsBaseHostedControl per utilizzare SafeDispatcher.
Analogamente a WPF Dispatcher, SafeDispatcher fornisce i metodi, ad esempio BeginInvoke, Invoke e InvokeAsync per eseguire le operazioni in modalità sincrona o asincrona in SafeDispatcher con un parametro booleano aggiuntivo, runOnMainUiThread, che controlla se eseguire SafeDispatcher nel thread dell'interfaccia utente oppure no.
SafeDispatcher offre i seguenti vantaggi:
Thread dispatcher protetto dell'interfaccia utente: gli sviluppatori possono eseguire le operazioni dipendenti dall'interfaccia utente in SafeDispatcher impostando il parametro runOnMainUiThread su "true" nel metodo di chiamata per eseguire SafeDispatcher nel thread dell'interfaccia utente. Qualsiasi eccezione non gestita sollevata nel dispatcher dell'interfaccia utente principale verrà gestita al livello di controllo ospitato anziché arrivare al gestore eventi globali DispatcherUnhandledException.
Thread dispatcher non protetto dell'interfaccia utente: gli sviluppatori possono eseguire qualsiasi codice indipendente dall'interfaccia utente in SafeDispatcher impostando il parametro runOnMainUiThread su "false" nel metodo di chiamata per eseguire SafeDispatcher nel thread non dell'interfaccia utente. Qualsiasi eccezione non gestita sollevata nel dispatcher non dell'interfaccia utente principale verrà gestita al livello di controllo ospitato anziché arrivare al gestore eventi globali DispatcherUnhandledException.
Informazioni dettagliate sull'origine e sulla causa dell'eccezione:: la gestione eccezioni di SafeDispatcher si verifica quando un'eccezione non gestita viene generata a livello di DynamicsBaseHostedControl dall'interfaccia utente o da un thread non dell'interfaccia utente, che consente a Unified Service Desk di acquisire le informazioni critiche a livello di controllo ospitato, quali ad esempio il nome del controllo ospitato, il tipo di controllo ospitato, il nome del metodo e la traccia dello stack di completamento per identificare la posizione e la causa esatte dell'eccezione.
Configurare o sostituire il gestore eccezioni SafeDispatcher: gli sviluppatori possono utilizzare il comportamento predefinito della gestione eccezioni SafeDispatcher per richiedere all'utente le informazioni sull'eccezione non gestita o sostituire il comportamento in base alle esigenze aziendali, come configurare la registrazione aggiuntiva, chiudere i controlli basati sulle sessioni o uscire dal client Unified Service Desk.
Come utilizzare SafeDispatcher?
La proprietà SafeDispatcher è disponibile per tutte le istanze di tipo controllo ospitato personalizzato Unified Service Desk che derivano dalla classe DynamicsBaseHostedControl. Un'istanza di SafeDispatcher è disponibile per l'esecuzione nel thread dell'interfaccia utente quando il controllo ospitato personalizzato è inizializzato. Tuttavia, un'istanza di SafeDispatcher sarà disponibile solo per l'esecuzione nel thread non dell'interfaccia utente quando esegui per la prima volta il metodo di chiamata.
Chiamata in modalità sincrona di una funzione specifica dell'interfaccia utente tramite SafeDispatcher
SafeDispatcher.Invoke(() => { ProcessData(); }, DispatcherPriority.Normal, CancellationToken.None, true);OR
SafeDispatcher.Invoke(() => { ProcessData(); }, DispatcherPriority.Normal, CancellationToken.None);Nota
Per la funzione specifica dell'interfaccia utente devi impostare il parametro facoltativo runOnMainUiThread su "true". Se non specifichi un valore per questo parametro, il valore predefinito passato è "true". Pertanto, una qualsiasi delle definizioni sopra riportate funziona correttamente.
Chiamare in modalità asincrona di una funzione specifica dell'interfaccia utente tramite SafeDispatcher. Puoi usare il metodo BeginInvoke o InvokeAsync.
SafeDispatcher.BeginInvoke(new Action(() => { ProcessData(); }));OR
SafeDispatcher.InvokeAsync(new Action(() => { ProcessData(); }));
Personalizzare il gestore eccezioni SafeDispatcher
Con l'introduzione di SafeDispatcher, tutte le eccezioni non gestite in Unified Service Desk generano l'evento SafeDispatcherUnhandledException Event anziché l'evento globale DispatcherUnhandledException. Il SafeDispatcherUnhandledExceptionHandler Method fornisce una gestione eccezioni predefinita per SafeDispatcher per la visualizzazione delle informazioni all'utente Unified Service Desk con i dettagli seguenti: controllo del codice sorgente in cui l'eccezione si è verificata e informazioni dettagliate sull'eccezione.
Puoi inoltre sostituire la gestione delle eccezioni predefinita per SafeDispatcher per eseguire altre operazioni, come la richiesta all'utente di chiudere un controllo ospitato non dinamico basato su sessione.
Nel seguente esempio di codice viene illustrato come puoi sostituire la gestione eccezioni SafeDispatcher predefinita per visualizzare una finestra di messaggio per richiedere all'utente di chiudere il controllo ospitato personalizzato quando si verifica un'eccezione:
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); });
}
}
Migrazione da WPF Dispatcher a SafeDispatcher in controlli ospitati personalizzati esistenti
Poiché il contratto tra WPF Dispatcher e SafeDispatcher è pressoché identico, l'impegno per il passaggio da WPF Dispatcher a SafeDispatcher è minimo. Per eseguire la migrazione di una qualsiasi istanza di controllo ospitato derivata dalla classe DynamicsBaseHostedControl, sostituisci tutte le istanze di "Dispatcher" con "SafeDispatcher".
Considera ad esempio il codice seguente:
Dispatcher.Invoke((System.Action)delegate()
{
DynamicsLogger.Logger.Log("Raising SetupHotKey's", TraceEventType.Verbose);
SetupHotkeys();
CRMGlobalManager.AppWithFocusChanged += CRMGlobalManager_AppWithFocusChanged;
FireEvent("DesktopReady");
InitializeFocusSelection();
});
Sostituisci Dispatcher nel codice sopra riportato con SafeDispatcher; il resto di codice rimane uguale:
SafeDispatcher.Invoke((System.Action)delegate()
{
DynamicsLogger.Logger.Log("Raising SetupHotKey's", TraceEventType.Verbose);
SetupHotkeys();
CRMGlobalManager.AppWithFocusChanged += CRMGlobalManager_AppWithFocusChanged;
FireEvent("DesktopReady");
InitializeFocusSelection();
});
Elementi da considerare quando si utilizza SafeDispatcher
SafeDispatcher offre un modello multithread che è molto utile nell'invio di funzioni in modalità sincrona o asincrona a thread dell'interfaccia utente o non dell'interfaccia utente. Le operazioni che devono essere eseguite nei thread disponibili con tolleranza d'errore devono essere eseguite in SafeDispatcher. Il multithreading deve essere implementato con molta attenzione per evitare blocchi critici tra i thread. Un esempio è l'invio dal thread non dell'interfaccia utente al WPF Dispatcher principale in modalità sincrona. Consideriamo questo esempio:
Thread thread = new Thread(() =>
{
Dispatcher.Invoke(ProcessData);
});
thread.SetApartmentState(ApartmentState.STA);
thread.Priority = ThreadPriority.Highest;
thread.IsBackground = true;
thread.Start();
thread.Join();
Il metodo thread.Join() sta causando il blocco del thread principale in attesa della chiusura del thread STA (single-threaded apartment), ma il thread di STA è in attesa che il thread principale completi l'esecuzione di ProcessData. Questo causa una situazione di blocco critico dell'app.
Analogamente, considera l'esempio seguente:
// Invoke on STA thread
SafeDispatcher.Invoke(() =>
{
// Invoke back on main dispatcher
SafeDispatcher.Invoke(() =>
{
ProcessData();
});
}, false);
Il SafeDispatcherUnhandledExceptionHandler Method sarà chiamato se un'eccezione si verifica nel WPF Dispatcher o nel thread STA non dell'interfaccia utente e viene generata nel rispettivo thread in cui l'eccezione si è verificata. Ti consigliamo di assicurarti di non inserire la combinazione precedente in questo gestore, ovvero, se l'eccezione si è verificata nel thread non dell'interfaccia utente, non inviare in modalità sincrona al dispatcher principale dell'interfaccia utente.
protected override void SafeDispatcherUnhandledExceptionHandler(object sender, SafeDispatcherUnhandledExceptionEventArgs ex)
{
Dispatcher.Invoke(LogException); // Incorrect
SafeDispatcher.Invoke(LogException); // Incorrect
SafeDispatcher.BeginInvoke(LogException); // Correct
SafeDispatcher.InvokeAsync(LogException); // Correct
}
Vedere anche
Procedura dettagliata: Creare un controllo ospitato personalizzato per Unified Service Desk
Estendere Unified Service Desk
TechNet: Configurare la registrazione della diagnostica del client in Unified Service Desk
Unified Service Desk 2.0
© 2017 Microsoft. Tutti i diritti sono riservati. Copyright