Beispiel #1
0
        /// <summary>
        /// It's a hack to manually Dispose Roslyns cache because GC fails with permissions exception.
        /// </summary>
        /// <remarks>
        ///     Currently Roslyn's MetadataCache stores AssembliesFromFiles property that stores information about object metadata.
        ///		But it doesn't clean it, so it will be cleaned by GC. but the problem with GC that it will be executed with lower permissions that it needs
        ///		AssembliesFromFiles uses WinApi to create MemoryMappedFile
        /// </remarks>
        private static void TryCleanRoslynCacheHack()
        {
            if (!SandboxHelper.IsInstanceInsideRunContainer())
            {
                return;
            }


            // increase to FullTrust
            new PermissionSet(PermissionState.Unrestricted).Assert();

            var type     = Type.GetType("Roslyn.Compilers.MetadataCache, Roslyn.Compilers");
            var property = type.GetProperty("AssembliesFromFiles", BindingFlags.Static | BindingFlags.NonPublic);
            var dict     = property.GetValue(null) as IDictionary;

            if (dict == null)
            {
                return;
            }

            if (dict.Count != 0)
            {
                var          caches             = dict.Values;
                FieldInfo    weakReferenceField = null;
                PropertyInfo targetProp         = null;
                foreach (var cache in caches)
                {
                    // init it
                    if (weakReferenceField == null)
                    {
                        weakReferenceField = cache.GetType().GetField("Metadata");
                        var tmp = weakReferenceField.GetValue(cache);

                        targetProp = tmp.GetType().GetProperty("Target", BindingFlags.Instance | BindingFlags.NonPublic);
                    }

                    var weakReference = weakReferenceField.GetValue(cache);

                    var obj = targetProp.GetValue(weakReference);
                    ((IDisposable)obj).Dispose();
                }
            }
            dict.Clear();
        }