IKVM11  11
Java SE 11 Virtual Machine for .NET
Loading...
Searching...
No Matches
ExecutionContext.NetCore.cs
Go to the documentation of this file.
1#if NETCOREAPP
2
3using System;
4using System.Reflection;
5using System.Runtime.Loader;
6using System.Text.Json;
7using System.Threading;
8using System.Threading.Tasks;
9
10namespace IKVM.Tools.Importer
11{
12
13 partial class ExecutionContext
14 {
15
19 class ExecutionContextDispatcher
20 {
21
22 readonly string[] _args;
23
29 public ExecutionContextDispatcher(string args)
30 {
31 if (args is null)
32 throw new ArgumentNullException(nameof(args));
33
34 _args = JsonSerializer.Deserialize<string[]>(args);
35 }
36
41 public int Execute()
42 {
43 return Task.Run(() => ImportTool.ExecuteInContext(_args)).GetAwaiter().GetResult();
44 }
45
46 }
47
51 class IsolatedAssemblyLoadContext : AssemblyLoadContext
52 {
53
54 readonly AssemblyDependencyResolver _resolver;
55
61 public IsolatedAssemblyLoadContext(string name, bool isCollectible = true) :
62 base(name, isCollectible)
63 {
64 _resolver = new AssemblyDependencyResolver(Assembly.GetEntryAssembly().Location);
65 }
66
67 protected override Assembly Load(AssemblyName assemblyName)
68 {
69 return _resolver.ResolveAssemblyToPath(assemblyName) is string p ? base.LoadFromAssemblyPath(p) : base.Load(assemblyName);
70 }
71
72 }
73
74 IsolatedAssemblyLoadContext _context;
75 object _dispatcher;
76
82 public ExecutionContext(string[] args)
83 {
84 // load the importer in a nested assembly context
85 _context = new IsolatedAssemblyLoadContext("IkvmImporter", true);
86 var asm = _context.LoadFromAssemblyName(typeof(ExecutionContextDispatcher).Assembly.GetName());
87 var typ = asm.GetType(typeof(ExecutionContextDispatcher).FullName);
88 _dispatcher = Activator.CreateInstance(typ, [JsonSerializer.Serialize(args)]);
89 }
90
97 public partial async Task<int> ExecuteAsync(CancellationToken cancellationToken)
98 {
99 return await Task.Run(() => (int)_dispatcher.GetType().GetMethod(nameof(ExecutionContextDispatcher.Execute), BindingFlags.Public | BindingFlags.Instance).Invoke(_dispatcher, []));
100 }
101
105 public void Dispose()
106 {
107 try
108 {
109 _dispatcher = null;
110 if (_context != null)
111 _context.Unload();
112 }
113 finally
114 {
115 _context = null;
116 }
117
118 GC.SuppressFinalize(this);
119 }
120
121 }
122
123}
124
125#endif
IKVM.Reflection.Assembly Assembly
IKVM.Reflection.AssemblyName AssemblyName
partial Task< int > ExecuteAsync(CancellationToken cancellationToken)
Executes the importer logic.