2016-06-23 6 views
0

Ich möchte eine entschuldigende Nachricht anzeigen und schließen Sie meine WPF-Anwendung, wenn eine Anfrage an Elasticsearch fehlschlägt. Es gibt viele Anfragen in der App, also denke ich am bequemsten ist, eine Ausnahme in OnRequestCompleted Callback zu werfen, wenn etwas schief geht und dann global zu behandeln. Aber jede von 4 Möglichkeiten, unbehandelte Ausnahmen zu behandeln, notierte here nichts und die App stürzt einfach ab. Hier ist das einfachste Beispiel. Was ist da falsch?Globale Behandlung der Ausnahme in OnRequestCompleted Rückruf

App.xaml

<Application x:Class="WPF_Elasticsearch_2._3.App" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      DispatcherUnhandledException="App_OnDispatcherUnhandledException" 
      StartupUri="MainWindow.xaml"> 
</Application> 

App.xaml.cs

using System; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Threading; 
using Nest; 

namespace WPF_Elasticsearch_2._3 
{ 
    public partial class App : Application 
    { 
     public static IElasticClient ElasticClient { get; private set; } 

     public App() 
     { 
      AppDomain.CurrentDomain.UnhandledException += App_OnUnhandledException; 
      TaskScheduler.UnobservedTaskException += App_OnUnobservedTaskException; 
      Dispatcher.UnhandledException += App_OnDispatcherUnhandledException; 

      var connectionSettings = new ConnectionSettings(new Uri("http://localhost:9200")) 
       .OnRequestCompleted(callDetails => 
       { 
        if (!callDetails.Success) 
         throw new Exception("Unsuccessful request!"); 
       }); 

      ElasticClient = new ElasticClient(connectionSettings); 
     } 

     private void App_OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) 
     { 
      MessageBox.Show(e.Exception.Message); 
      e.Handled = true; 
      Shutdown(-1); 
     } 

     private void App_OnUnhandledException(object sender, UnhandledExceptionEventArgs e) 
     { 
      MessageBox.Show(((Exception)e.ExceptionObject).Message); 
      Shutdown(-1); 
     } 

     private void App_OnUnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e) 
     { 
      MessageBox.Show(e.Exception.Message); 
      e.SetObserved(); 
      Shutdown(-1); 
     } 
    } 
} 

MainWindow.xaml

<Window x:Class="WPF_Elasticsearch_2._3.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     mc:Ignorable="d" 
     Title="MainWindow" Height="240" Width="320"> 

    <Button Click="ButtonBase_OnClick">Make request</Button> 
</Window> 

MainWindow.xaml.cs

using System.Windows; 

namespace WPF_Elasticsearch_2._3 
{ 
    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private void ButtonBase_OnClick(object sender, RoutedEventArgs e) 
     { 
      App.ElasticClient.Search<object>(descriptor => descriptor 
       .Index("test-index") 
       .Type("test-type")); 
     } 
    } 
} 
+0

verwenden Sie verschiedene appDomains? Haben Sie versucht, den EventHandler-Code für OnRequestCompleted in eine "echte Methode" zu verschieben, anstatt einen anonymen Code zu verwenden? Sie benötigen möglicherweise eine Aufforderung? – Mat

+1

Ich würde nicht wirklich auf den Beitrag achten, den du verlinkt hast. Wenn Sie Ihre eigene Exception werfen wollen, müssen Sie sie trotzdem irgendwo behandeln, sonst wird die Anwendung zum Absturz gebracht. In dieser Hinsicht, um das gewünschte Verhalten zu erhalten, müssen Sie wahrscheinlich keine Ausnahme auslösen, Sie können einfach das Verhalten erzeugen, das Sie wollen, wo Sie die Ausnahme werfen. Um Ausnahmen zu behandeln, sollten Sie einen "try/catch" -Baustein verwenden. – pay

+0

@pay Einige wichtige, aber wichtige Fragen folgen von dort: - Was ist das Konzept von unbehandelten Ausnahmeereignissen für und wie kann es funktionieren? ? - Wo sollte ich den try/catch-Block platzieren, um alle Ausnahmen behandeln zu können? Konsolen- und WinForms-Apps verfügen im Gegensatz zu WPF über eine einfach zu verstehende Main-Methode. Ich würde nicht nur etwas Verhalten hervorbringen, weil die App eine komplexe Struktur hat und es möglicherweise andere Meldungen über Fehler gibt, wenn die erste Nachricht auf dem Bildschirm erscheint, und ich muss alles stoppen, wenn der Fehler passiert ist. –

Antwort

1

können Sie configure the client to throw on exceptions

var connectionSettings = new ConnectionSettings(new Uri("http://localhost:9200")) 
     .ThrowExceptions(); 

var client = new ElasticClient(connectionSettings); 

Auf diese Weise verwenden, werden Sie nicht eine Ausnahme in .OnRequestCompleted() werfen müssen.

Wie andere in den Kommentaren jedoch gesagt haben, müssen Sie diese Ausnahmen in irgendeiner Weise behandeln; Wenn Sie .ThrowExceptions() verwenden, können Sie Ihre Anrufe in try/catch Blöcke umbrechen, die eine Nachricht an die Benutzeroberfläche signalisieren, wenn eine Elasticsearch-Ausnahme in catch abgefangen wird.