forked from dotnet/docs
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathunloadability_issues_example_main.cs
77 lines (64 loc) · 2.36 KB
/
unloadability_issues_example_main.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Loader;
namespace example
{
class TestAssemblyLoadContext : AssemblyLoadContext
{
public TestAssemblyLoadContext() : base(true)
{
}
protected override Assembly? Load(AssemblyName name)
{
return null;
}
}
class TestInfo
{
public TestInfo(MethodInfo? mi)
{
_entryPoint = mi;
}
MethodInfo? _entryPoint;
}
class Program
{
static TestInfo? entryPoint;
[MethodImpl(MethodImplOptions.NoInlining)]
static int ExecuteAndUnload(string assemblyPath, out WeakReference testAlcWeakRef, out MethodInfo? testEntryPoint)
{
var alc = new TestAssemblyLoadContext();
testAlcWeakRef = new WeakReference(alc);
Assembly a = alc.LoadFromAssemblyPath(assemblyPath);
if (a == null)
{
testEntryPoint = null;
Console.WriteLine("Loading the test assembly failed");
return -1;
}
var args = new object[1] {new string[] {"Hello"}};
// Issue preventing unloading #1 - we keep MethodInfo of a method
// for an assembly loaded into the TestAssemblyLoadContext in a static variable.
entryPoint = new TestInfo(a.EntryPoint);
testEntryPoint = a.EntryPoint;
var oResult = a.EntryPoint?.Invoke(null, args);
alc.Unload();
return (oResult is int result) ? result : -1;
}
static void Main(string[] args)
{
WeakReference testAlcWeakRef;
// Issue preventing unloading #2 - we keep MethodInfo of a method for an assembly loaded into the TestAssemblyLoadContext in a local variable
MethodInfo? testEntryPoint;
int result = ExecuteAndUnload(@"absolute/path/to/test.dll", out testAlcWeakRef, out testEntryPoint);
for (int i = 0; testAlcWeakRef.IsAlive && (i < 10); i++)
{
GC.Collect();
GC.WaitForPendingFinalizers();
}
System.Diagnostics.Debugger.Break();
Console.WriteLine($"Test completed, result={result}, entryPoint: {testEntryPoint} unload success: {!testAlcWeakRef.IsAlive}");
}
}
}