/// <summary> /// Loads the specified set of resources by creating template language generators and loading /// the content asynchronously. /// </summary> /// <remarks>Once LoadAsync() is completed, the manager is fully initialized. Note that the this set up supports /// GenerateASync() being called in the generators in other threads while we are loading, and the thread-safe lazy initialization /// is ensuring that a single thread initializes the resources.</remarks> /// <param name="resources">Resources to load.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> private async Task LoadAsync(IEnumerable <Resource> resources) { var loadTaskMap = new Dictionary <Resource, (Task LoadTask, TemplateEngineLanguageGenerator Generator)>(); // Create one LanguageGenerator for each resource. Given that each language generator needs // to asynchronous load its content, we trigger these loading tasks async and them wait for them all to be done. foreach (var resource in resources) { // Create generator, explicitly asking to not load resources on construction so we can do it asynchronously. var generator = new TemplateEngineLanguageGenerator(resource, _multilanguageResources); // Capture loading task and store in temporary map. var generatorLoadTask = generator.LoadAsync(); loadTaskMap.Add(resource, (generatorLoadTask, generator)); } // Wait for loading to complete. await Task.WhenAll(loadTaskMap.Select(entry => entry.Value.LoadTask)).ConfigureAwait(false); // Build our language generator table with the fully loaded generators. foreach (var entry in loadTaskMap) { LanguageGenerators[entry.Key.Id] = new Lazy <LanguageGenerator>(() => entry.Value.Generator); } }
/// <summary> /// Populates the <see cref="LanguageGenerators"/> property with <see cref="Lazy{LaguageGenerator}" /> instances. /// </summary> /// <remarks> /// If the resource contains exports, this method also ensure the LanguageGenerator instance is loaded and ready to use. /// </remarks> private void PopulateLanguageGenerators() { var resources = _resourceExplorer.GetResources("lg"); // Create one LanguageGenerator for each resource. foreach (var resource in resources) { LanguageGenerators[resource.Id] = new Lazy <LanguageGenerator>(() => { // Creates the generator when requested and loads it. var generator = new TemplateEngineLanguageGenerator(resource, _multilanguageResources); generator.LoadAsync().GetAwaiter().GetResult(); return(generator); }); // Check if the file contains exports. if (ContainsExport(resource)) { // Force lazy creation for lg files that contain exports // Exports need to be available globally and need to be parsed at startup _ = LanguageGenerators[resource.Id].Value; } } }