System.Net.AutoWebProxyScriptWrapper.CreateAppDomain C# (CSharp) Method

CreateAppDomain() private method

private CreateAppDomain ( ) : void
return void
        private void CreateAppDomain()
        {
            // Locking s_AppDomains must happen in a CER so we don't orphan a lock that gets taken by AppDomain.DomainUnload.
            bool lockHeld = false;
            RuntimeHelpers.PrepareConstrainedRegions();
            try
            {
                try { }
                finally
                {
                    Monitor.Enter(s_AppDomains.SyncRoot);
                    lockHeld = true;
                }

                if (s_CleanedUp)
                {
                    throw new InvalidOperationException(SR.GetString(SR.net_cant_perform_during_shutdown));
                }

                // Create singleton.
                if (s_AppDomainInfo == null)
                {
                    s_AppDomainInfo = new AppDomainSetup();
                    s_AppDomainInfo.DisallowBindingRedirects = true;
                    s_AppDomainInfo.DisallowCodeDownload = true;

                    NamedPermissionSet perms = new NamedPermissionSet("__WebProxySandbox", PermissionState.None);
                    perms.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
                }

                // If something's already in s_ExcessAppDomain, try to dislodge it again.
                AppDomain excessAppDomain = s_ExcessAppDomain;
                if (excessAppDomain != null)
                {
                    TimerThread.GetOrCreateQueue(0).CreateTimer(new TimerThread.Callback(CloseAppDomainCallback), excessAppDomain);
                    throw new InvalidOperationException(SR.GetString(SR.net_cant_create_environment));
                }

                appDomainIndex = s_NextAppDomainIndex++;
                try { }
                finally
                {
                    //                                                                                                            
                    s_ExcessAppDomain = AppDomain.CreateDomain(c_appDomainName, null, s_AppDomainInfo);

                    try
                    {
                        s_AppDomains.Add(appDomainIndex, s_ExcessAppDomain);

                        // This indicates to the finally and the finalizer that everything succeeded.
                        scriptDomain = s_ExcessAppDomain;
                    }
                    finally
                    {
                        // ReferenceEquals has a ReliabilityContract.
                        if (object.ReferenceEquals(scriptDomain, s_ExcessAppDomain))
                        {
                            s_ExcessAppDomain = null;
                        }
                        else
                        {
                            // Something failed.  Leave the domain in s_ExcessAppDomain until we can get rid of it.  No
                            // more AppDomains can be created until we do.  In the mean time, keep attempting to get the
                            // TimerThread to remove it.  Also, might as well remove it from the hash if it made it in.
                            try
                            {
                                s_AppDomains.Remove(appDomainIndex);
                            }
                            finally
                            {
                                // Can't call AppDomain.Unload from a user thread (or in a lock).
                                TimerThread.GetOrCreateQueue(0).CreateTimer(new TimerThread.Callback(CloseAppDomainCallback), s_ExcessAppDomain);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (lockHeld)
                {
                    Monitor.Exit(s_AppDomains.SyncRoot);
                }
            }
        }