WPF async/await in application_startup

di il
2 risposte

WPF async/await in application_startup

Buondì

Avrei bisogno di eseguire un metodo asincrono all'inizio della mia applicazione WPF, prima di aprire qualsiasi finestra.

Il metodo utilizza il paradigma async/await ma non ho trovato un sistema valido per risolvere questa cosa.

In internet si trovano le seguenti opzioni:

  • Usare GetAwaiter().GetResult()
  • Usare Wait()
  • Esiste la libreria AsyncAwaitBestPractice che ha il metodo SafeFireAndForget

Nessuno di questi metodi funziona, poichè la chiamata va in blocco.

So che il problema è la gestione di async/await allo startup, perchè se la stessa chiamata la faccio alla pressione di un pulsante (quindi rientrando nel giro “standard” di async/await) tutto funziona

Qualcuno sa come posso fare? 

2 Risposte

  • Re: WPF async/await in application_startup

    01/08/2023 - PiGi78 ha scritto:


    Il metodo utilizza il paradigma async/await ma non ho trovato un sistema valido per risolvere questa cosa.

    Prova a postare il codice, perché (almeno per quanto mi riguarda) la problematica non è chiarissima.

  • Re: WPF async/await in application_startup

    Praticamente si tratta di autenticare l'utente usando Azure AD B2C.

    La metodologia da utilizzare è quella riportata in questo post di Microsoft: https://learn.microsoft.com/en-us/samples/azure-samples/active-directory-dotnet-native-aspnetcore-v2/1-desktop-app-calls-web-api/

    Ho wrappato la parte di accesso ad Azure in una classe statica di utilità per l'applicazione:

     internal static class AzureClient
     {
    
            /// <summary>
            /// Costruttore
            /// </summary>
            static AzureClient()
            {
                PublicClientApp = PublicClientApplicationBuilder.Create(ClientId)
                    .WithB2CAuthority(AuthoritySignUpSignIn)
                    .WithRedirectUri(RedirectUri)
                    .WithLogging(Log, LogLevel.Info, true)
                    .Build();
    
                TokenCacheHelper.Bind(PublicClientApp.UserTokenCache);
            }
    
    
            /// <summary>
            /// Login su Azure AD
            /// </summary>
            public static async Task LoginAsync()
            {
                await PublicClientApp.AcquireTokenInteractive(ApiScopes).ExecuteAsync();
                var accounts = await PublicClientApp.GetAccountsAsync(PolicySignUpSignIn);
                CurrentAccount = accounts.FirstOrDefault();
            }
            
            
    ... qui ci sono tutte le proprietà di Azure che non riporto per questioni di sicurezza,
            
        però trovate gli esempi nel post di Microsoft se vi servono...
     }
    

    PublicClientApp è l'istanza della classe IPublicClientApplication sviluppata da Microsoft per accedere ad Azure (quindi do per scontato che sia scritta in modo corretto).

    Il metodo che crea problemi è LoginAsync

    Come si può vedere, fa solo delle chiamate a metodi di PublicClientApp usando il paradigma async/await

    Il problema è questo:

    • Se cerco di chiamare il metodo LoginAsync allo startup dell'applicazione, la procedura chiede utente/password ma si blocca (in debug non esce mai dalla chiamata LoginAsync)
    • Se metto la chiamata nella MainWindow dell'applicazione alla pressione di un pulsante, tutto funziona bene

    PS: Ho già controllato e la classe PublicClientApp ha solo i metodi “Async”, quindi non posso chiamare Execute() o GetAccounts() poichè non esistono

Devi accedere o registrarti per scrivere nel forum
2 risposte