Sfoglia il codice sorgente

Background ScriptDocument initialization

Kenric Nugteren 1 anno fa
parent
commit
6e43bdb588
1 ha cambiato i file con 61 aggiunte e 42 eliminazioni
  1. 61 42
      inabox.scripting/ScriptDocument.cs

+ 61 - 42
inabox.scripting/ScriptDocument.cs

@@ -9,6 +9,7 @@ using System.Reflection;
 using System.Runtime.CompilerServices;
 using System.Text.RegularExpressions;
 using System.Threading;
+using System.Threading.Tasks;
 using InABox.Core;
 using Microsoft.CodeAnalysis;
 using Microsoft.CodeAnalysis.CSharp.Scripting;
@@ -66,7 +67,9 @@ public class ScriptDocument : INotifyPropertyChanged
         Properties = new List<ScriptProperty>();
     }
 
-    public static RoslynHost Host { get; private set; }
+    private static Task<RoslynHost> _hostTask;
+    private static RoslynHost? _host;
+    public static RoslynHost Host => _host ?? InitializeHost().Result;
 
     public static FluentList<Assembly> DefaultAssemblies { get; }
 
@@ -98,51 +101,67 @@ public class ScriptDocument : INotifyPropertyChanged
 
     private static IEnumerable<MetadataReference> CompilationReferences;
 
+    private static Task<RoslynHost> InitializeHost()
+    {
+        _hostTask ??= Task.Run(() =>
+        {
+            using var profiler = new Profiler(true, "ScriptDocument");
+            var assemblies = new HashSet<Assembly>();
+            var typelist = CoreUtils.TypeList(
+                AppDomain.CurrentDomain.GetAssemblies(),
+                x =>
+                {
+                    if (x.IsClass && !x.IsGenericType && x.IsSubclassOf(typeof(BaseObject)))
+                    {
+                        var module = x.Assembly.Modules.FirstOrDefault();
+                        if(module != null && !module.FullyQualifiedName.Equals("<Unknown>"))
+                        {
+                            assemblies.Add(x.Assembly);
+                            return true;
+                        }
+                    }
+                    return false;
+                });
+            DefaultAssemblies.AddRange(assemblies);
+
+            var references = Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "refs"), "*.dll")
+                .Select(x => MetadataReference.CreateFromFile(x)).ToArray();
+
+            var files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll").Where(
+                x => !Path.GetFileName(x).ToLower().StartsWith("gsdll")
+                     && !Path.GetFileName(x).ToLower().StartsWith("pdfium")
+                     && !Path.GetFileName(x).ToLower().StartsWith("ikvm-native")
+                     && !Path.GetFileName(x).ToLower().StartsWith("sqlite.interop")
+                     && !Path.GetFileName(x).ToLower().StartsWith("microsoft.codeanalysis")
+            );
+
+            var hostReferences = RoslynHostReferences.NamespaceDefault.With(
+                typeNamespaceImports: typelist
+                //, assemblyReferences: DefaultAssemblies
+                , assemblyPathReferences: files,
+                references: references
+            );
+            CompilationReferences = RoslynHostReferences.NamespaceDefault.With(
+                typeNamespaceImports: typelist
+                , assemblyReferences: DefaultAssemblies
+                , assemblyPathReferences: files
+            ).GetReferences();
+
+            _host = new RoslynHost(
+                DefaultAssemblies.ToArray(),
+                hostReferences
+            );
+            return _host;
+        });
+        return _hostTask;
+    }
+
     public static void Initialize()
     {
-        var typelist = CoreUtils.TypeList(
-            AppDomain.CurrentDomain.GetAssemblies(),
-            x =>
-                x.GetTypeInfo().IsClass
-                && !x.GetTypeInfo().IsGenericType
-                && x.GetTypeInfo().IsSubclassOf(typeof(BaseObject))).ToList();
-        for (var i = typelist.Count - 1; i > -1; i--) // var type in typelist)
+        if(_hostTask is null)
         {
-            var type = typelist[i];
-            var module = type.Assembly.Modules.FirstOrDefault();
-            if (module != null && !module.FullyQualifiedName.Equals("<Unknown>"))
-                DefaultAssemblies.Add(type.Assembly);
-            else
-                typelist.RemoveAt(i);
+            InitializeHost();
         }
-
-        var references = Directory.GetFiles(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "refs"), "*.dll")
-            .Select(x => MetadataReference.CreateFromFile(x)).ToArray();
-
-        var files = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll").Where(
-            x => !Path.GetFileName(x).ToLower().StartsWith("gsdll")
-                 && !Path.GetFileName(x).ToLower().StartsWith("pdfium")
-                 && !Path.GetFileName(x).ToLower().StartsWith("ikvm-native")
-                 && !Path.GetFileName(x).ToLower().StartsWith("sqlite.interop")
-                 && !Path.GetFileName(x).ToLower().StartsWith("microsoft.codeanalysis")
-        );
-
-        var hostReferences = RoslynHostReferences.NamespaceDefault.With(
-            typeNamespaceImports: typelist
-            //, assemblyReferences: DefaultAssemblies
-            , assemblyPathReferences: files,
-            references: references
-        );
-        CompilationReferences = RoslynHostReferences.NamespaceDefault.With(
-            typeNamespaceImports: typelist
-            , assemblyReferences: DefaultAssemblies
-            , assemblyPathReferences: files
-        ).GetReferences();
-
-        Host = new RoslynHost(
-            DefaultAssemblies.ToArray(),
-            hostReferences
-        );
     }
 
     public bool Compile()