Jaa


SafeDispatcherin käyttäminen mukautetuissa isännöidyissä ohjausobjekteissa Unified Service Desk -ratkaisussa

Unified Service Desk on Windows Presentation Foundation (WPF) -pohjainen sovellus, jossa kaikki Unified Service Desk -ratkaisun toiminnot suoritetaan WPF Dispatcher -pääsäikeessä. WPF Dispatcher -luokka tarjoaa palveluita säikeen työkohteiden jonon hallintaan.

Voit laajentaa Unified Service Desk -ratkaisua luomalla mukautettuja ohjausobjekteja ja isännöimällä sitä Unified Service Desk -ratkaisussa. Jos mukautettu isännöity ohjausobjekti sisältää virheellistä koodia tai suorittaa toimintoja uusien säikeiden avulla käsittelemättä poikkeuksia asianmukaisesti koodin suorittamisen aikana, se voi aiheuttaa vakausongelmia Unified Service Desk -ratkaisussa ja jopa aiheuttaa asiakassovelluksen jumiutumisen tai vastaamattomuuden. Kolmannen osapuolen mukautettujen ohjausobjektien käsittelemättömät poikkeukset tekevät ongelman tunnistamisesta, vianmäärityksestä ja ratkaisemisesta haastavaa tuote-/tukiryhmälle, koska heillä ei ehkä ole pääsyä tietoihin, miksi virhe tai poikkeus tapahtui Unified Service Desk -ratkaisussa, ja virheen aiheuttaneeseen tarkkaan koodiin.

Esittelyssä SafeDispatcher, joka tarjoaa tehokkaan ja informatiivisen poikkeusten käsittelymekanismin mukautetuille isännöidyille ohjausobjekteille Unified Service Desk -ratkaisussa tarjoamalla käsittelemättömien poikkeusten käyttövalmiin kirjaamisen, jossa on yksityiskohtaisia tietoja poikkeuksen lähteestä ja syystä, ja antamalla sinun määrittää tai korvata SafeDispatcher-poikkeusten käsittelyn joidenkin muiden vaiheiden suorittamista varten. Tämä estää myös Unified Service Desk -asiakasohjelmaa lakkaamasta vastaamasta mukautetun isännöidyn ohjausobjektin koodin käsittelemättömien poikkeusten vuoksi.

Mikä on SafeDispatcher?

SafeDispatcher on rakennettu samoille linjoille kuin WPF Dispatcher, ja se tarjoaa joustavan ja informatiivisen poikkeusten käsittelyn mukautetuille isännöidyille ohjausobjekteille Unified Service Desk -ratkaisussa. Se näkyy suojattuna SafeDispatcher-ominaisuutenaDynamicsBaseHostedControl-luokassa , jolloin SafeDispatcher on automaattisesti käytettävissä kaikissa Unified Service Desk -ratkaisun mukautetuissa isännöidyissä ohjausobjekteissa, jotka on johdettu DynamicsBaseHostedControl-luokasta .

Huomautus

Älä käytä koodissasi olevaa SafeDispatcher-luokkaa SafeDispatcherin käyttämiseen. Sen sijaan sinun on käytettävä SafeDispatcher-ominaisuutta mukautetussa isännöidyn ohjausobjektin esiintymässä, joka on johdettu DynamicsBaseHostedControl-luokasta , jotta voit käyttää SafeDispatcheria.

WPF Dispatcherin tavoin SafeDispatcher tarjoaa menetelmiä, kuten BeginInvoke, Invoke ja InvokeAsync, jotka suorittavat toimintoja synkronisesti tai asynkronisesti SafeDispatcherissa ylimääräisellä totuusarvoparametrilla, joka määrittää, runOnMainUiThreadsuoritetaanko SafeDispatcher käyttöliittymäsäikeessä vai ei.

SafeDispatcher tarjoaa seuraavat edut:

  • Suojattu käyttöliittymän lähettäjän säie: Kehittäjät voivat suorittaa kaikki käyttöliittymästä riippuvaiset toiminnot SafeDispatcherissa määrittämällä parametriksi runOnMainUiThread "true" invoke-menetelmässä, jotta SafeDispatcher on UI -säikeen voidaan suorittaa. Kaikki käyttöliittymän pääohjaimessa syntyneet käsittelemättömät poikkeukset käsitellään turvallisesti isännöidyn ohjausobjektin tasolla sen sijaan, että ne kuplivat yleiseen DispatcherUnhandledException-tapahtumakäsittelijään .

  • Suojattu ei-käyttöliittymän Dispatcher-säie: Kehittäjät voivat suorittaa kaiken käyttöliittymästä riippumattoman koodin SafeDispatcherissa. määrittämällä parametriksi runOnMainUiThread "false" invoke-menetelmässä, jotta SafeDispatcher suoritetaan muussa kuin käyttöliittymäsäikeessä. Kaikki käsittelemättömät poikkeukset, jotka on nostettu pääasiallisessa ei-käyttöliittymän aikatauluttajassa, käsitellään turvallisesti isännöidyn ohjausobjektin tasolla sen sijaan, että ne kuplivat yleiseen DispatcherUnhandledException-tapahtumakäsittelijään .

  • Tarkempia tietoja poikkeuksen lähteestä ja syystä: SafeDispatcher-poikkeuskäsittelijä käynnistetään, kun käyttöliittymä tai muu kuin käyttöliittymäsäie nostaa käsittelemättömän poikkeuksen DynamicsBaseHostedControl-tasolla , jolloin Unified Service Desk voi tallentaa isännöidyn ohjausobjektin tasolla tärkeitä tietoja, kuten isännöidyn ohjausobjektin nimen, isännöidyn ohjausobjektin tyypin, menetelmän nimen ja täydellisen pinon jäljityksen, jotta poikkeuksen tarkka sijainti ja syy voidaan tunnistaa.

  • SafeDispatcher-poikkeuskäsittelijän määrittäminen tai ohittaminen: Kehittäjät voivat käyttää SafeDispatcher-poikkeuskäsittelijän käyttövalmiita toimintoja pyytääkseen käyttäjältä tietoja käsittelemättömästä poikkeuksesta tai ohittaakseen toiminnan liiketoimintatarpeidensa mukaisesti, kuten määrittääkseen lisäkirjaamisen, sulkeakseen istuntoon perustuvia ohjausobjekteja tai poistuakseen Unified Service Desk -asiakasohjelmasta.

Kuinka käyttää SafeDispatcheria?

SafeDispatcher-ominaisuus on käytettävissä kaikissa mukautetuissa Unified Service Desk -ratkaisun isännöidyissä ohjausobjekteissa, jotka on johdettu DynamicsBaseHostedControl-luokasta. SafeDispatcher-esiintymä on käytettävissä käyttöliittymäsäikeessä, kun mukautettu isännöity ohjausobjekti alustetaan. SafeDispatcher-esiintymä on kuitenkin käytettävissä vain muussa kuin käyttöliittymäsäikeessä, kun suoritat invoke-menetelmän ensimmäisen kerran.

  • Käyttöliittymäkohtaisen toiminnon synkroninen käynnistäminen SafeDispatcherin avulla

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

    TAI

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

    Huomautus

    Käyttöliittymäkohtaista toimintoa varten sinun tulee asettaa runOnMainUiThread valinnaiseksi parametriksi "true". Jos et määritä arvoa tälle parametrille, oletusarvoisesti välitetään "true". Joten mikä tahansa yllä olevista menetelmämäärityksistä toimii hyvin.

  • Käynnistä käyttöliittymäkohtainen funktio asynkronisesti SafeDispatcherin avulla. Voit käyttää joko tai-menetelmää BeginInvokeInvokeAsync .

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

    TAI

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

SafeDispatcher-poikkeuskäsittelijän mukauttaminen

SafeDispatcherin käyttöönoton myötä kaikki Unified Service Desk -ratkaisun käsittelemättömät poikkeukset tuovat esiin SafeDispatcherUnhandledException-tapahtuman yleisen DispatcherUnhandledException-tapahtuman sijaan. SafeDispatcherUnhandledExceptionHandler-menetelmä tarjoaa SafeDispatcherille käyttövalmiin poikkeuskäsittelijän, joka näyttää Unified Service Desk -käyttäjälle seuraavat tiedot: lähteen ohjausobjekti, jossa poikkeus tapahtui, ja yksityiskohtaiset tiedot poikkeuksesta.

Voit myös ohittaa SafeDispatcherin käyttövalmiin poikkeusten käsittelyn suorittaaksesi muita toimintoja, kuten pyytääksesi käyttäjää sulkemaan istuntopohjaisen ei-dynaamisen isännöidyn ohjausobjektin.

Seuraavassa esimerkkikoodissa näytetään, miten voit ohittaa käyttövalmiin SafeDispatcher-poikkeuskäsittelijän ja näyttää sanomaruudun, joka kehottaa käyttäjää sulkemaan mukautetun isännöidyn ohjausobjektin poikkeuksen ilmetessä:

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

Siirtyminen WPF Dispatcherista SafeDispatcheriin aiemmin luoduissa mukautetuissa isännöidyissä ohjausobjekteissa

Koska WPF Dispatcherin ja SafeDispatcherin välinen sopimus on lähes identtinen, WPF Dispatcherista SafeDispatcheriin siirtyminen on vähäistä. Jos haluat siirtää minkä tahansa DynamicsBaseHostedControl-luokasta johdetun isännöidyn ohjausobjektin ilmentymän, korvaa kaikki Dispatcher-esiintymät SafeDispatcher-esiintymällä.

Katso esimerkiksi seuraavaa koodia:

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

Korvaa Dispatcher yllä olevassa koodissa ; SafeDispatchermuu koodi pysyy samana:

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

Huomioitavia asioita SafeDispatcheria käytettäessä

SafeDispatcher tarjoaa monisäikeisen mallin, joka on erittäin hyödyllinen toimintojen lähettämisessä synkronisesti tai asynkronisesti käyttöliittymään tai ei-käyttöliittymäsäikeeseen. Toiminnot, jotka on suoritettava säikeissä, jotka ovat käytettävissä vikasietoisuudella, on suoritettava SafeDispatcherissa. Monisäikeisyys tulee kuitenkin toteuttaa erittäin huolellisesti, jotta vältetään kierteiden välinen umpikuja. Yksi tällainen esimerkki on lähettäminen muusta kuin käyttöliittymäsäikeestä WPF-päälähettäjään synkronisesti. Tarkastellaanpa tätä esimerkkiä:

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

Menetelmä thread.Join() aiheuttaa pääsäikeen estymisen odotettaessa yksisäikeisen asunto (STA) -säikeen päättymistä, mutta STA-säie odottaa pääsäikeen suorittavan ProcessData loppuun. Tämä aiheuttaa sovelluksesi umpikujaan.

Tarkastellaan vastaavasti seuraavaa esimerkkiä:

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

SafeDispatcherUnhandledExceptionHandler-menetelmää kutsutaan, jos poikkeus tapahtuu WPF Dispatcherissa tai STA:n muussa kuin käyttöliittymäsäikeessä, ja se käynnistetään vastaavassa säikeessä, jossa poikkeus tapahtui. Varmista varoen, ettet sijoita yllä olevaa yhdistelmää tähän käsittelijään, eli jos poikkeus tapahtui muussa kuin käyttöliittymäsäikeessä, älä lähetä synkronisesti käyttöliittymän pääaikatauluttajaan.

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

Katso myös

Mukautetun Unified Service Desk -isännöidyn ohjausobjektin luominenUnified Service Desk -ratkaisun laajentaminenAsiakkaan diagnostiikan kirjaamisen määrittäminen Unified Service Desk -ratkaisussa