/// <summary>
        ///     Returns the <see cref="HierarchyId"/> of the given document moniker, or
        ///     <see cref="HierarchyId.Nil"/> if the document moniker is not part of the project.
        /// </summary>
        public static HierarchyId GetHierarchyId(this IVsProject project, string documentMoniker)
        {
            Requires.NotNull(project, nameof(project));
            Requires.NotNullOrEmpty(documentMoniker, nameof(documentMoniker));

            var     priority = new VSDOCUMENTPRIORITY[1];
            int     isFound;
            uint    itemId;
            HResult result = project.IsDocumentInProject(documentMoniker, out isFound, priority, out itemId);

            if (result.Failed)
            {
                throw result.Exception;
            }

            // We only return items that are actually part of the project. CPS returns non-member from this API.
            if (isFound == 0 || priority[0] != VSDOCUMENTPRIORITY.DP_Standard && priority[0] != VSDOCUMENTPRIORITY.DP_Intrinsic)
            {
                return(HierarchyId.Nil);
            }

            HierarchyId id = itemId;

            Assumes.False(id.IsNilOrEmpty);

            return(id);
        }
        private async Task <(HierarchyId itemid, IVsHierarchy?hierarchy, IVsContainedLanguageFactory?containedLanguageFactory)> GetContainedLanguageFactoryForFileAsync(string filePath)
        {
            await _projectContextHost.PublishAsync();

            await _projectVsServices.ThreadingService.SwitchToUIThread();

            var     priority = new VSDOCUMENTPRIORITY[1];
            HResult result   = _projectVsServices.VsProject.IsDocumentInProject(filePath, out int isFound, priority, out uint itemid);

            if (result.Failed || isFound == 0)
            {
                return(HierarchyId.Nil, null, null);
            }

            Assumes.False(itemid == HierarchyId.Nil);

            IVsContainedLanguageFactory?containedLanguageFactory = await _containedLanguageFactory.GetValueAsync();

            if (containedLanguageFactory == null)
            {
                return(HierarchyId.Nil, null, null);
            }

            return(itemid, _projectVsServices.VsHierarchy, containedLanguageFactory);
        }
Exemple #3
0
        /// <summary>
        /// Transitions this queue to a completed state if signaled and the queue is empty.
        /// </summary>
        private void CompleteIfNecessary()
        {
            Assumes.False(Monitor.IsEntered(this.SyncRoot)); // important because we'll transition a task to complete.

            bool transitionTaskSource, invokeOnCompleted = false;

            lock (this.SyncRoot)
            {
                transitionTaskSource = this.completeSignaled && (this.queueElements == null || this.queueElements.Count == 0);
                if (transitionTaskSource)
                {
                    invokeOnCompleted       = !this.onCompletedInvoked;
                    this.onCompletedInvoked = true;
                    while (this.dequeuingWaiters?.Count > 0)
                    {
                        this.dequeuingWaiters.Dequeue().TrySetCanceled();
                    }
                }
            }

            if (transitionTaskSource)
            {
                this.completedSource?.TrySetResult(null);
                if (invokeOnCompleted)
                {
                    this.OnCompleted();
                }
            }
        }
            public DimensionConfigurationCommand(string dimensionName, ImmutableArray <string> dimensionValues)
            {
                DimensionName = dimensionName;
                Command       = new DelegateCommand <Property>(
                    property =>
                {
                    bool isAdding = !property.Values.Any(value => value.ConfigurationDimensions.ContainsKey(dimensionName));

                    if (isAdding)
                    {
                        property.Values = property.Values
                                          .SelectMany(value => dimensionValues.Select(dim => new PropertyValue(value.UnevaluatedValue, value.EvaluatedValue, value.ConfigurationDimensions.Add(dimensionName, dim))))
                                          .ToImmutableArray();
                    }
                    else
                    {
                        Assumes.False(property.Values.IsEmpty);
                        var oldValueGroups = property.Values.GroupBy(value => value.ConfigurationDimensions.Remove(dimensionName), DimensionValueEqualityComparer.Instance);

                        property.Values = oldValueGroups
                                          .Select(group => new PropertyValue(group.First().UnevaluatedValue, group.First().EvaluatedValue, group.First().ConfigurationDimensions.Remove(dimensionName)))
                                          .ToImmutableArray();
                    }
                });
            }
Exemple #5
0
        /// <summary>
        /// Initializes static members of the <see cref="KSec"/> class.
        /// </summary>
        static KSec()
        {
            IntPtr handle = Dlfcn.dlopen(Constants.SecurityLibrary, 0);

            Assumes.False(handle == IntPtr.Zero);

            try
            {
                AttrApplicationTag = Dlfcn.GetStringConstant(handle, "kSecAttrApplicationTag");
                AttrKeyType        = Dlfcn.GetStringConstant(handle, "kSecAttrKeyType");
                AttrKeySizeInBits  = Dlfcn.GetStringConstant(handle, "kSecAttrKeySizeInBits");
                AttrKeyTypeRSA     = Dlfcn.GetStringConstant(handle, "kSecAttrKeyTypeRSA");
                AttrIsPermanent    = Dlfcn.GetStringConstant(handle, "kSecAttrIsPermanent");
                PublicKeyAttrs     = Dlfcn.GetStringConstant(handle, "kSecPublicKeyAttrs");
                PrivateKeyAttrs    = Dlfcn.GetStringConstant(handle, "kSecPrivateKeyAttrs");
                ClassKey           = Dlfcn.GetStringConstant(handle, "kSecClassKey");
                Class                      = Dlfcn.GetStringConstant(handle, "kSecClass");
                AttrKeyClass               = Dlfcn.GetStringConstant(handle, "kSecAttrKeyClass");
                AttrKeyClassPublic         = Dlfcn.GetStringConstant(handle, "kSecAttrKeyClassPublic");
                AttrKeyClassPrivate        = Dlfcn.GetStringConstant(handle, "kSecAttrKeyClassPrivate");
                ReturnData                 = Dlfcn.GetStringConstant(handle, "kSecReturnData");
                ReturnPersistentRef        = Dlfcn.GetStringConstant(handle, "kSecReturnPersistentRef");
                AttrAccessibleWhenUnlocked = Dlfcn.GetStringConstant(handle, "kSecAttrAccessibleWhenUnlocked");
                AttrAccessible             = Dlfcn.GetStringConstant(handle, "kSecAttrAccessible");
                ReturnRef                  = Dlfcn.GetStringConstant(handle, "kSecReturnRef");
                ValueData                  = Dlfcn.GetStringConstant(handle, "kSecValueData");
            }
            finally
            {
                Dlfcn.dlclose(handle);
            }
        }
Exemple #6
0
        /// <summary>
        /// Cancels all outstanding dequeue tasks for the specified CancellationToken.
        /// </summary>
        /// <param name="state">A <see cref="Tuple{AsyncQueue, CancellationToken}"/> instance.</param>
        private static void CancelDequeuers(object state)
        {
            var                  tuple             = (Tuple <AsyncQueue <T>, CancellationToken>)state;
            AsyncQueue <T>       that              = tuple.Item1;
            CancellationToken    ct                = tuple.Item2;
            CancellableDequeuers cancelledAwaiters = null;

            lock (that.syncObject)
            {
                if (that.dequeuingTasks != null && that.dequeuingTasks.TryGetValue(ct, out cancelledAwaiters))
                {
                    that.dequeuingTasks.Remove(ct);
                }
            }

            // This work can invoke external code and mustn't happen within our private lock.
            Assumes.False(Monitor.IsEntered(that.syncObject)); // important because we'll transition a task to complete.
            if (cancelledAwaiters != null)
            {
                foreach (var awaiter in cancelledAwaiters)
                {
                    awaiter.SetCanceled();
                }

                cancelledAwaiters.Dispose();
            }
        }
        protected override async Task InitializeCoreAsync(CancellationToken cancellationToken)
        {
            IProjectGuidService2 projectGuidService = ProjectGuidServices.FirstOrDefault()?.Value as IProjectGuidService2;

            if (projectGuidService == null)
            {
                return;
            }

            _projectGuid = await projectGuidService.GetProjectGuidAsync()
                           .ConfigureAwait(false);

            Assumes.False(_projectGuid == Guid.Empty);

            _startupProjectsListService = (IVsStartupProjectsListService)await _serviceProvider.GetServiceAsync(typeof(SVsStartupProjectsListService))
                                          .ConfigureAwait(false);

            Assumes.Present(_startupProjectsListService);

            _subscription = _projectSubscriptionService.ProjectRuleSource.SourceBlock.LinkTo(
                target: new ActionBlock <IProjectVersionedValue <IProjectSubscriptionUpdate> >(OnProjectChangedAsync),
                suppressVersionOnlyUpdates: true,
                linkOptions: new DataflowLinkOptions()
            {
                PropagateCompletion = true
            });
        }
Exemple #8
0
        private async Task <(HierarchyId itemid, IVsHierarchy hierarchy, IVsContainedLanguageFactory containedLanguageFactory)> GetContainedLanguageFactoryForFileAsync(string filePath)
        {
            await _languageServiceHost.InitializeAsync();

            await _projectVsServices.ThreadingService.SwitchToUIThread();

            var     priority = new VSDOCUMENTPRIORITY[1];
            HResult result   = _projectVsServices.VsProject.IsDocumentInProject(filePath, out int isFound, priority, out uint itemid);

            if (result.Failed || isFound == 0)
            {
                return(HierarchyId.Nil, null, null);
            }

            Assumes.False(itemid == HierarchyId.Nil);

            IVsContainedLanguageFactory containedLanguageFactory = await _containedLanguageFactory.GetValueAsync();

            if (containedLanguageFactory == null)
            {
                return(HierarchyId.Nil, null, null);
            }

            var hierarchy = (IVsHierarchy)_projectHostProvider.UnconfiguredProjectHostObject.ActiveIntellisenseProjectHostObject;

            if (hierarchy == null)
            {
                return(HierarchyId.Nil, null, null);
            }

            return(itemid, hierarchy, containedLanguageFactory);
        }
Exemple #9
0
            /// <summary>
            /// Validates this node and all its descendents.
            /// </summary>
            public static void ValidateInternalIntegrity(TRecursiveParent parent)
            {
                // Each node id appears at most once.
                if (parent.Children?.Count > 0)
                {
                    var observedIdentities = new System.Collections.Generic.HashSet <IdentityFieldType>();
                    foreach (var node in parent.GetSelfAndDescendents())
                    {
                        if (!observedIdentities.Add(node.Identity))
                        {
                            throw new RecursiveChildNotUniqueException(node.Identity);
                        }
                    }
                }

                // The lookup table (if any) accurately describes the contents of this tree.
                if (parent.LookupTable != null && parent.LookupTable != LazySentinel)
                {
                    // The table should have one entry for every *descendent* of this node (not this node itself).
                    int expectedCount = parent.GetSelfAndDescendents().Count() - 1;
                    int actualCount   = parent.LookupTable.Count;
                    Assumes.False(actualCount != expectedCount, "Expected {0} entries in lookup table but found {1}.", expectedCount, actualCount);

                    ValidateLookupTable(parent, parent.LookupTable);
                }
            }
 public void False()
 {
     Assumes.False(false);
     Assert.ThrowsAny <Exception>(() => Assumes.False(true, TestMessage));
     Assert.ThrowsAny <Exception>(() => Assumes.False(true, TestMessage, "arg1"));
     Assert.ThrowsAny <Exception>(() => Assumes.False(true, TestMessage, "arg1", "arg2"));
 }
        private void HandleDesignTime(IProjectVersionedValue <IProjectSubscriptionUpdate> update, IWorkspaceProjectContext context, bool isActiveContext)
        {
            Assumes.False(update.Value.ProjectChanges.Count == 0, "CPS should never send us an empty design-time build data.");

            IComparable version = update.DataSourceVersions[ProjectDataSources.ConfiguredProjectVersion];

            using (IProjectLoggerBatch logger = _logger.BeginBatch())
            {
                string ruleName = CompilerCommandLineArgs.SchemaName;

                WriteHeader(logger, update, version, RuleHandlerType.DesignTimeBuild, isActiveContext);
                WriteRuleHeader(logger, ruleName);

                IProjectChangeDescription projectChange = update.Value.ProjectChanges[ruleName];

                // If nothing changed (even another failed design-time build), don't do anything
                if (projectChange.Difference.AnyChanges)
                {
                    ProcessOptions(projectChange, context, logger);
                    ProcessItems(version, projectChange, context, isActiveContext, logger);
                    ProcessDesignTimeBuildFailure(projectChange, context, logger);
                }
                else
                {
                    WriteRuleHasNoChanges(logger);
                }

                WriteRuleFooter(logger, ruleName);
                WriteFooter(logger, update);
            }
        }
Exemple #12
0
            public int Consume(byte[] buffer, int offset, int count)
            {
                int copiedBytes = Math.Min(count, this.Buffer.Length - this.Position);

                Array.Copy(this.Buffer, this.Position, buffer, offset, copiedBytes);
                this.Position += copiedBytes;
                Assumes.False(this.Position > this.Buffer.Length);
                return(copiedBytes);
            }
        protected override async Task InitializeCoreAsync(CancellationToken cancellationToken)
        {
            _projectGuid = await _projectGuidService.GetProjectGuidAsync();

            Assumes.False(_projectGuid == Guid.Empty);

            _subscription = _projectSubscriptionService.ProjectRuleSource.SourceBlock.LinkToAsyncAction(
                target: OnProjectChangedAsync);
        }
        protected override async Tasks.Task InitializeCoreAsync(CancellationToken cancellationToken)
        {
            ConfigurationGeneral projectProperties =
                await _projectVsServices.ActiveConfiguredProjectProperties.GetConfigurationGeneralPropertiesAsync().ConfigureAwait(false);

            _guid = new Guid((string)await projectProperties.ProjectGuid.GetValueAsync().ConfigureAwait(false));
            Assumes.False(_guid == Guid.Empty);

            await InitializeAsync().ConfigureAwait(false);
        }
Exemple #15
0
 private void SetState(MessageHandlerState startingOperation)
 {
     lock (this.syncObject)
     {
         Verify.NotDisposed(this);
         MessageHandlerState state = this.state;
         Assumes.False(state.HasFlag(startingOperation));
         this.state |= startingOperation;
     }
 }
        private static string BuildPropertyName(string eventName, string propertyName)
        {
            // Property names use the event names, but with slashes replaced by periods.
            // For example, vs/myevent would translate to vs.myevent.myproperty.
            string prefix = eventName.Replace('/', '.');

            Assumes.False(prefix.EndsWith("."));

            return(prefix + "." + propertyName.ToLowerInvariant());
        }
 private void EnableInitialSources()
 {
     Assumes.False(this.constructed);
     if (this.eventSourcesPresentAtConstruction != null)
     {
         EventSource eventSource;
         while (this.eventSourcesPresentAtConstruction.TryDequeue(out eventSource))
         {
             EnableAsNecessary(eventSource);
         }
     }
 }
 private void EnableInitialSources()
 {
     Assumes.False(this.constructed);
     if (this.eventSourcesPresentAtConstruction != null)
     {
         foreach (EventSource eventSource in this.eventSourcesPresentAtConstruction)
         {
             EnableAsNecessary(eventSource);
         }
         this.eventSourcesPresentAtConstruction.Clear(); // Do not hold onto EventSource references that are already initialized.
     }
 }
Exemple #19
0
        public async ValueTask <IReadOnlyList <ProjectAction> > GetUninstallActionsAsync(
            string projectId,
            PackageIdentity packageIdentity,
            bool removeDependencies,
            bool forceRemove,
            CancellationToken cancellationToken)
        {
            Assumes.NotNullOrEmpty(projectId);
            Assumes.NotNull(packageIdentity);
            Assumes.False(packageIdentity.HasVersion);
            Assumes.NotNull(_state.SourceCacheContext);
            Assumes.NotNull(_state.ResolvedActions);
            Assumes.Null(_state.PackageIdentity);

            cancellationToken.ThrowIfCancellationRequested();

            return(await CatchAndRethrowExceptionAsync(async() =>
            {
                INuGetProjectContext projectContext = await ServiceLocator.GetInstanceAsync <INuGetProjectContext>();
                (bool success, NuGetProject? project) = await TryGetNuGetProjectMatchingProjectIdAsync(projectId);

                Assumes.True(success);
                Assumes.NotNull(project);

                var projectActions = new List <ProjectAction>();
                var uninstallationContext = new UninstallationContext(removeDependencies, forceRemove);

                NuGetPackageManager packageManager = await _sharedState.PackageManager.GetValueAsync(cancellationToken);
                IEnumerable <NuGetProjectAction> actions = await packageManager.PreviewUninstallPackageAsync(
                    project,
                    packageIdentity.Id,
                    uninstallationContext,
                    projectContext,
                    cancellationToken);

                foreach (NuGetProjectAction action in actions)
                {
                    var resolvedAction = new ResolvedAction(project, action);
                    var projectAction = new ProjectAction(
                        CreateProjectActionId(),
                        projectId,
                        action.PackageIdentity,
                        action.NuGetProjectActionType,
                        implicitActions: null);

                    _state.ResolvedActions[projectAction.Id] = resolvedAction;

                    projectActions.Add(projectAction);
                }

                return projectActions;
            }));
        }
    public async Task GetBuildVersion_In_Git_But_Without_Commits()
    {
        Repository.Init(this.RepoPath);
        var repo = new Repository(this.RepoPath); // do not assign Repo property to avoid commits being generated later

        this.WriteVersionFile("3.4");
        Assumes.False(repo.Head.Commits.Any()); // verification that the test is doing what it claims
        var buildResult = await this.BuildAsync();

        Assert.Equal("3.4.0.0", buildResult.BuildVersion);
        Assert.Equal("3.4.0", buildResult.AssemblyInformationalVersion);
    }
            public bool IsInvalid()
            {
                // If we don't have these MSBuild values as a minimum, we cannot create a context.
                if (string.IsNullOrEmpty(LanguageName) || string.IsNullOrEmpty(BinOutputPath) || string.IsNullOrEmpty(ProjectFilePath))
                {
                    return(true);
                }

                Assumes.False(ProjectGuid == Guid.Empty);
                Assumes.NotNull(WorkspaceProjectContextId);

                return(false);
            }
Exemple #22
0
        public async ValueTask <IReadOnlyList <ProjectAction> > GetUninstallActionsAsync(
            IReadOnlyCollection <string> projectIds,
            PackageIdentity packageIdentity,
            bool removeDependencies,
            bool forceRemove,
            CancellationToken cancellationToken)
        {
            Assumes.NotNullOrEmpty(projectIds);
            Assumes.NotNull(packageIdentity);
            Assumes.False(packageIdentity.HasVersion);
            Assumes.NotNull(_state.SourceCacheContext);
            Assumes.Null(_state.PackageIdentity);
            Assumes.True(_state.ResolvedActions.Count == 0);

            cancellationToken.ThrowIfCancellationRequested();

            return(await CatchAndRethrowExceptionAsync(async() =>
            {
                INuGetProjectContext projectContext = await ServiceLocator.GetComponentModelServiceAsync <INuGetProjectContext>();
                IReadOnlyList <NuGetProject> projects = await GetProjectsAsync(projectIds, cancellationToken);

                var projectActions = new List <ProjectAction>();
                var uninstallationContext = new UninstallationContext(removeDependencies, forceRemove);

                NuGetPackageManager packageManager = await _sharedState.GetPackageManagerAsync(cancellationToken);
                IEnumerable <NuGetProjectAction> projectsWithActions = await packageManager.PreviewProjectsUninstallPackageAsync(
                    projects,
                    packageIdentity.Id,
                    uninstallationContext,
                    projectContext,
                    cancellationToken);

                foreach (NuGetProjectAction projectWithActions in projectsWithActions)
                {
                    var resolvedAction = new ResolvedAction(projectWithActions.Project, projectWithActions);
                    var projectAction = new ProjectAction(
                        CreateProjectActionId(),
                        projectWithActions.Project.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId),
                        projectWithActions.PackageIdentity,
                        projectWithActions.NuGetProjectActionType,
                        implicitActions: null);

                    _state.ResolvedActions[projectAction.Id] = resolvedAction;

                    projectActions.Add(projectAction);
                }

                return projectActions;
            }));
        }
Exemple #23
0
        public Task ReportFailureAsync(string failureReason, TimeSpan checkDuration, CancellationToken cancellationToken)
        {
            Assumes.False(_hasBeenReported);

            var telemetryEvent = new TelemetryEvent(TelemetryEventName.IncrementalBuildValidationFailure);

            telemetryEvent.Properties.Add(TelemetryPropertyName.IncrementalBuildFailureReason, failureReason);
            telemetryEvent.Properties.Add(TelemetryPropertyName.IncrementalBuildValidationDurationMillis, checkDuration);

            TelemetryService.DefaultSession.PostEvent(telemetryEvent);

            _hasBeenReported = true;

            return(Task.CompletedTask);
        }
Exemple #24
0
        protected override async Task InitializeCoreAsync(CancellationToken cancellationToken)
        {
            _projectGuid = await _projectGuidService.GetProjectGuidAsync()
                           .ConfigureAwait(false);

            Assumes.False(_projectGuid == Guid.Empty);

            _startupProjectsListService = (IVsStartupProjectsListService)await _serviceProvider.GetServiceAsync(typeof(SVsStartupProjectsListService))
                                          .ConfigureAwait(false);

            Assumes.Present(_startupProjectsListService);

            _subscription = _projectSubscriptionService.ProjectRuleSource.SourceBlock.LinkToAsyncAction(
                target: OnProjectChangedAsync);
        }
Exemple #25
0
        private void HandleDesignTime(IProjectVersionedValue <IProjectSubscriptionUpdate> update, IWorkspaceProjectContext context, bool isActiveContext)
        {
            Assumes.False(update.Value.ProjectChanges.Count == 0, "CPS should never send us an empty design-time build data.");

            IProjectChangeDescription projectChange = update.Value.ProjectChanges[CompilerCommandLineArgs.SchemaName];
            IComparable version = update.DataSourceVersions[ProjectDataSources.ConfiguredProjectVersion];

            // If nothing changed (even another failed design-time build), don't do anything
            if (projectChange.Difference.AnyChanges)
            {
                ProcessDesignTimeBuildFailure(projectChange, context);
                ProcessOptions(projectChange, context);
                ProcessItems(version, projectChange, context, isActiveContext);
            }
        }
        // Teardown Logic

        /// <summary>
        /// Tells the editor to call close on the existing window frame.
        /// </summary>
        /// <returns>True if the close was successful, false if the window is still open</returns>
        public async Task <bool> CanCloseWindowAsync()
        {
            // We can't switch to editor closing here because there's still the chance that some other action can cancel
            // the editor closing, without notifying us. A later callback will get hit once the close is guaranteed to happen.
            // We do, however, assert that we're not in NoEditor, Initializing, or EditorClosing; being in any of those states
            // here would indicate a bug.
            lock (_lock)
            {
                Assumes.False(_currentState == EditorState.NoEditor ||
                              _currentState == EditorState.Initializing ||
                              _currentState == EditorState.EditorClosing);
            }
            await _threadingService.SwitchToUIThread();

            return(_windowFrame.CloseFrame((uint)__FRAMECLOSE.FRAMECLOSE_PromptSave) == VSConstants.S_OK);
        }
 public void InternalErrorException_IsSerializable()
 {
     try
     {
         Assumes.False(true);
     }
     catch (Exception ex)
     {
         var formatter = new BinaryFormatter();
         var ms        = new MemoryStream();
         formatter.Serialize(ms, ex);
         ms.Position = 0;
         var ex2 = (Exception)formatter.Deserialize(ms);
         Assert.IsType(ex.GetType(), ex2);
         Assert.Equal(ex.Message, ex2.Message);
     }
 }
        public bool IsClearedTo(Fix current, Fix target)
        {
            Requires.NotNull(current, nameof(current));
            Requires.NotNull(target, nameof(target));
            Requires.That(this.FlightPath.Contains(current), nameof(current), "The 'current' fix is not part of the flight path");
            Requires.That(this.FlightPath.Contains(target), nameof(target), "The 'target' fix is not part of the flight path");
            Assumes.False(current == target, "Current fix cannot be the same as the target fix");

            int limitIndex   = this.FlightPath.IndexOf(this.LocationOrLimit);
            int currentIndex = this.FlightPath.IndexOf(current);
            int targetIndex  = this.FlightPath.IndexOf(target);

            bool sameDirection          = currentIndex < targetIndex;
            bool notGoingBeyondTheLimit = targetIndex <= limitIndex;

            return(sameDirection && notGoingBeyondTheLimit);
        }
    public void InternalErrorException_IsSerializable()
    {
        try
        {
            Assumes.False(true);
        }
#pragma warning disable CA1031 // Do not catch general exception types
        catch (Exception ex)
#pragma warning restore CA1031 // Do not catch general exception types
        {
            var formatter = new BinaryFormatter();
            using var ms = new MemoryStream();
            formatter.Serialize(ms, ex);
            ms.Position = 0;
            var ex2 = (Exception)formatter.Deserialize(ms);
            Assert.IsType(ex.GetType(), ex2);
            Assert.Equal(ex.Message, ex2.Message);
        }
    }
    public void SemaphoreWaiterJoinsSemaphoreHolders(ReentrantSemaphore.ReentrancyMode mode)
    {
        this.semaphore = this.CreateSemaphore(mode);
        this.ExecuteOnDispatcher(async delegate
        {
            var firstEntered = new AsyncManualResetEvent();
            bool firstOperationReachedMainThread = false;
            var firstOperation = Task.Run(async delegate
            {
                await this.semaphore.ExecuteAsync(
                    async delegate
                {
                    firstEntered.Set();
                    await this.joinableTaskContext.Factory.SwitchToMainThreadAsync(this.TimeoutToken);
                    firstOperationReachedMainThread = true;
                },
                    this.TimeoutToken);
            });

            bool secondEntryComplete = false;
            this.joinableTaskContext.Factory.Run(async delegate
            {
                await firstEntered.WaitAsync().WithCancellation(this.TimeoutToken);
                Assumes.False(firstOperationReachedMainThread);

                // While blocking the main thread, request the semaphore.
                // This should NOT deadlock if the semaphore properly Joins the existing semaphore holder(s),
                // allowing them to get to the UI thread and then finally to exit the semaphore so we can enter it.
                await this.semaphore.ExecuteAsync(
                    delegate
                {
                    secondEntryComplete = true;
                    Assert.True(firstOperationReachedMainThread);
                    return(TplExtensions.CompletedTask);
                },
                    this.TimeoutToken);
            });
            await Task.WhenAll(firstOperation).WithCancellation(this.TimeoutToken);
            Assert.True(secondEntryComplete);
        });
    }