From 789b4e35e5dca795cad584d8001acaf7f2c284c2 Mon Sep 17 00:00:00 2001 From: Siegfried Pammer Date: Thu, 25 Jun 2020 11:08:10 +0200 Subject: [PATCH] Reduce number of possible hiccups during MEF initialization by reducing the number of Task.GetAwaiter().GetResult() calls. --- ILSpy/App.xaml.cs | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/ILSpy/App.xaml.cs b/ILSpy/App.xaml.cs index f01ee49d6..5d5f5e36b 100644 --- a/ILSpy/App.xaml.cs +++ b/ILSpy/App.xaml.cs @@ -40,19 +40,12 @@ namespace ICSharpCode.ILSpy /// public partial class App : Application { - internal static CommandLineArguments CommandLineArguments; + internal static readonly IList StartupExceptions = new List(); - static ExportProvider exportProvider; - - public static ExportProvider ExportProvider => exportProvider; + public static ExportProvider ExportProvider { get; private set; } + public static IExportProviderFactory ExportProviderFactory { get; private set; } - static IExportProviderFactory exportProviderFactory; - - public static IExportProviderFactory ExportProviderFactory => exportProviderFactory; - - internal static readonly IList StartupExceptions = new List(); - internal class ExceptionData { public Exception Exception; @@ -77,7 +70,16 @@ namespace ICSharpCode.ILSpy Dispatcher.CurrentDispatcher.UnhandledException += Dispatcher_UnhandledException; } TaskScheduler.UnobservedTaskException += DotNet40_UnobservedTaskException; + InitializeMef().GetAwaiter().GetResult(); + Languages.Initialize(ExportProvider); + EventManager.RegisterClassHandler(typeof(Window), + Hyperlink.RequestNavigateEvent, + new RequestNavigateEventHandler(Window_RequestNavigate)); + ILSpyTraceListener.Install(); + } + private static async Task InitializeMef() + { // Cannot show MessageBox here, because WPF would crash with a XamlParseException // Remember and show exceptions in text output, once MainWindow is properly initialized try { @@ -93,7 +95,7 @@ namespace ICSharpCode.ILSpy var name = Path.GetFileNameWithoutExtension(plugin); try { var asm = Assembly.Load(name); - var parts = discovery.CreatePartsAsync(asm).GetAwaiter().GetResult(); + var parts = await discovery.CreatePartsAsync(asm); catalog = catalog.AddParts(parts); } catch (Exception ex) { StartupExceptions.Add(new ExceptionData { Exception = ex, PluginName = name }); @@ -101,28 +103,22 @@ namespace ICSharpCode.ILSpy } } // Add the built-in parts - catalog = catalog.AddParts(discovery.CreatePartsAsync(Assembly.GetExecutingAssembly()).GetAwaiter().GetResult()); + var createdParts = await discovery.CreatePartsAsync(Assembly.GetExecutingAssembly()); + catalog = catalog.AddParts(createdParts); // If/When the project switches to .NET Standard/Core, this will be needed to allow metadata interfaces (as opposed // to metadata classes). When running on .NET Framework, it's automatic. // catalog.WithDesktopSupport(); // If/When any part needs to import ICompositionService, this will be needed: // catalog.WithCompositionService(); var config = CompositionConfiguration.Create(catalog); - exportProviderFactory = config.CreateExportProviderFactory(); - exportProvider = exportProviderFactory.CreateExportProvider(); + ExportProviderFactory = config.CreateExportProviderFactory(); + ExportProvider = ExportProviderFactory.CreateExportProvider(); // This throws exceptions for composition failures. Alternatively, the configuration's CompositionErrors property // could be used to log the errors directly. Used at the end so that it does not prevent the export provider setup. config.ThrowOnErrors(); } catch (Exception ex) { StartupExceptions.Add(new ExceptionData { Exception = ex }); } - - Languages.Initialize(exportProvider); - - EventManager.RegisterClassHandler(typeof(Window), - Hyperlink.RequestNavigateEvent, - new RequestNavigateEventHandler(Window_RequestNavigate)); - ILSpyTraceListener.Install(); } protected override void OnStartup(StartupEventArgs e)