IHost.RunAsync e IHost.StopAsync generano un'eccezione quando un BackgroundService fallisce

Quando un BackgroundService fallisce a causa di un'eccezione nel suo metodo ExecuteAsync e HostOptions.BackgroundServiceExceptionBehavior è impostato su StopHost (impostazione predefinita), l'host si arresta. In .NET 11, le attività restituite da RunAsync, StopAsync, WaitForShutdownAsync e gli equivalenti sincroni hanno ora esito negativo con un'eccezione anziché completare correttamente.

Versione introdotta

.NET 11 Preview 3

Comportamento precedente

In precedenza, quando BackgroundService veniva generata un'eccezione dal suo metodo ExecuteAsync e HostOptions.BackgroundServiceExceptionBehavior era impostata su BackgroundServiceExceptionBehavior.StopHost, l'attività restituita dalla chiamata a RunAsync, StopAsync o WaitForShutdownAsync si completava correttamente. Ciò significa in genere che l'applicazione è stata chiusa con un codice di uscita riuscito (zero).

Nuovo comportamento

A partire da .NET 11, quando un genera un'eccezione dal relativo metodo /> è impostato su , l'attività restituita dalla chiamata di , o ha esito negativo con un'eccezione. L'applicazione viene in genere chiusa con un codice di uscita dell'errore (diverso da zero).

  • Se un singolo servizio ha esito negativo, viene generata di nuovo l'eccezione generata dal servizio.
  • Se più servizi hanno esito negativo, le relative eccezioni vengono combinate in un oggetto AggregateException.

Tipo di cambiamento che interrompe la compatibilità

Questa modifica è una modifica funzionale.

Motivo della modifica

Se un'applicazione si arresta a causa di un errore, non deve uscire con un codice di uscita riuscito. Il comportamento precedente nasconde l'errore, rendendo più difficile rilevare e diagnosticare l'eccezione che lo ha causato.

L'azione consigliata consiste nell'eseguire alcuna operazione. Un'applicazione con errori deve uscire con un codice di uscita dell'errore, ovvero il nuovo comportamento.

Se è necessario mantenere il comportamento precedente e uscire con un codice di uscita di successo, inserire await o StopAsync all'interno di un blocco try-catch:

try
{
    await host.RunAsync();
}
catch (Exception ex)
{
    // Log or inspect the exception if needed.
}

Le API interessate