public bool TryEnterOnCurrentStack() { #if NETFRAMEWORK || NETSTANDARD2_0 try { RuntimeHelpers.EnsureSufficientExecutionStack(); return(true); } catch (InsufficientExecutionStackException) { } #else if (RuntimeHelpers.TryEnsureSufficientExecutionStack()) { return(true); } #endif if (_executionStackCount < MaxExecutionStackCount) { return(false); } throw new InsufficientExecutionStackException(); }
public bool TryEnterOnCurrentStack() { #if NETCOREAPP2_0 if (RuntimeHelpers.TryEnsureSufficientExecutionStack()) {//尝试确保有足够的堆栈来执行平均 .NET Core 库函数 return(true); } #else try { RuntimeHelpers.EnsureSufficientExecutionStack();//确保剩余的堆栈控件足够大,可以执行一般的 .NET 函数 return(true); } catch (InsufficientExecutionStackException) { } #endif if (_executionStackCount < MaxExecutionStackCount) { return(false); } throw new InsufficientExecutionStackException(); }
/// <inheritdoc/> public void Execute(ResolveRequestContext context, Action <ResolveRequestContext> next) { if (!(context.Operation is IDependencyTrackingResolveOperation dependencyTrackingResolveOperation)) { // Skipping circular dependency detection, since IResolveOperation is not IDependencyTrackingResolveOperation // Which contains the actual RequestStack using SegmentStack next(context); return; } var activationDepth = context.Operation.RequestDepth; if (activationDepth > _maxResolveDepth) { #if NETSTANDARD2_1 // In .NET Standard 2.1 we will try and keep going until we run out of stack space. if (!RuntimeHelpers.TryEnsureSufficientExecutionStack()) { throw new DependencyResolutionException(string.Format(CultureInfo.CurrentCulture, CircularDependencyDetectorMessages.MaxDepthExceeded, context.Service)); } #else // Pre .NET Standard 2.1 we just end at 50. throw new DependencyResolutionException(string.Format(CultureInfo.CurrentCulture, CircularDependencyDetectorMessages.MaxDepthExceeded, context.Service)); #endif } var requestStack = dependencyTrackingResolveOperation.RequestStack; // The first one is the current resolve request. // Do our circular dependency check. if (activationDepth > 1) { var registration = context.Registration; foreach (var requestEntry in requestStack) { if (requestEntry.Registration == registration) { throw new DependencyResolutionException(string.Format( CultureInfo.CurrentCulture, CircularDependencyDetectorMessages.CircularDependency, CreateDependencyGraphTo(registration, requestStack))); } } } requestStack.Push(context); try { // Circular dependency check is done, move to the next stage. next(context); } finally { requestStack.Pop(); } }
public bool TryEnterOnCurrentStack() { if (RuntimeHelpers.TryEnsureSufficientExecutionStack()) { return(true); } if (_executionStackCount < MaxExecutionStackCount) { return(false); } throw new InsufficientExecutionStackException(); }
private static void FillStack(int depth) { // This test will fail with a StackOverflowException if TryEnsureSufficientExecutionStack() doesn't // return false. No exception is thrown and the test finishes when TryEnsureSufficientExecutionStack() // returns true. if (!RuntimeHelpers.TryEnsureSufficientExecutionStack()) { Assert.Throws <InsufficientExecutionStackException>(() => RuntimeHelpers.EnsureSufficientExecutionStack()); return; } else if (depth < 2048) { FillStack(depth + 1); } }
/// <summary>Tries to ensure there is sufficient stack to execute the average .NET function.</summary> public static bool TryEnsureSufficientExecutionStack() { #if REGEXGENERATOR try { RuntimeHelpers.EnsureSufficientExecutionStack(); return(true); } catch { return(false); } #else return(RuntimeHelpers.TryEnsureSufficientExecutionStack()); #endif }
/// <summary>Copies that ending state information from <paramref name="task"/> to <paramref name="completionSource"/>.</summary> private static bool TrySetFromTask <TResult>(this TaskCompletionSource <TResult> completionSource, Task task) { Debug.Assert(task.IsCompleted); // Before transferring the results, check to make sure we're not too deep on the stack. Calling TrySet* // will cause any synchronous continuations to be invoked, which is fine unless we're so deep that doing // so overflows. ContinueWith has built-in support for avoiding such stack dives, but that support is not // (yet) part of await's infrastructure, so until it is we mimic it manually. This matches the behavior // employed by the Unwrap implementation in mscorlib. if (!RuntimeHelpers.TryEnsureSufficientExecutionStack()) { // This is very rare. We're too deep to safely invoke // TrySet* synchronously, so do so asynchronously instead. Task.Factory.StartNew(s => { var t = (Tuple <TaskCompletionSource <TResult>, Task>)s; TrySetFromTask(t.Item1, t.Item2); }, Tuple.Create(completionSource, task), CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default); return(true); } // Transfer the results from the supplied Task to the TaskCompletionSource. bool result = false; switch (task.Status) { case TaskStatus.Canceled: result = completionSource.TrySetCanceled(ExtractCancellationToken(task)); break; case TaskStatus.Faulted: result = completionSource.TrySetException(task.Exception.InnerExceptions); break; case TaskStatus.RanToCompletion: Task <TResult> resultTask = task as Task <TResult>; result = resultTask != null? completionSource.TrySetResult(resultTask.Result) : completionSource.TrySetResult(default(TResult)); break; } return(result); }
//////////////////////////////////////////////////////////// // // Internal overridable methods // /// <summary> /// Attempts to execute the target task synchronously. /// </summary> /// <param name="task">The task to run.</param> /// <param name="taskWasPreviouslyQueued">True if the task may have been previously queued, /// false if the task was absolutely not previously queued.</param> /// <returns>True if it ran, false otherwise.</returns> internal bool TryRunInline(Task task, bool taskWasPreviouslyQueued) { // Do not inline unstarted tasks (i.e., task.ExecutingTaskScheduler == null). // Do not inline TaskCompletionSource-style (a.k.a. "promise") tasks. // No need to attempt inlining if the task body was already run (i.e. either TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bits set) TaskScheduler?ets = task.ExecutingTaskScheduler; // Delegate cross-scheduler inlining requests to target scheduler if (ets != this && ets != null) { return(ets.TryRunInline(task, taskWasPreviouslyQueued)); } if ((ets == null) || (task.m_action == null) || task.IsDelegateInvoked || task.IsCanceled || !RuntimeHelpers.TryEnsureSufficientExecutionStack()) { return(false); } // Task class will still call into TaskScheduler.TryRunInline rather than TryExecuteTaskInline() so that // 1) we can adjust the return code from TryExecuteTaskInline in case a buggy custom scheduler lies to us // 2) we maintain a mechanism for the TLS lookup optimization that we used to have for the ConcRT scheduler (will potentially introduce the same for TP) if (TplEventSource.Log.IsEnabled()) { task.FireTaskScheduledIfNeeded(this); } bool inlined = TryExecuteTaskInline(task, taskWasPreviouslyQueued); // If the custom scheduler returned true, we should either have the TASK_STATE_DELEGATE_INVOKED or TASK_STATE_CANCELED bit set // Otherwise the scheduler is buggy if (inlined && !(task.IsDelegateInvoked || task.IsCanceled)) { throw new InvalidOperationException(SR.TaskScheduler_InconsistentStateAfterTryExecuteTaskInline); } return(inlined); }
public static void TryEnsureSufficientExecutionStack_SpaceAvailable_ReturnsTrue() { Assert.True(RuntimeHelpers.TryEnsureSufficientExecutionStack()); }
protected override WrappedObject TryParse(ParseContext ctx) { var clone = ctx.Clone(); ctx.Properties.WrappedObjectCount++; var typePattern = new TypePatternElement(); var possibleValues = new List <(int CurrentPosition, List <ParseMatch> expression, ParseResult result)>(); var startPos = clone.CurrentPosition; foreach (var type in WorkspaceManager.CurrentWorkspace.TypesManager.KnownTypesFromAddons) { //Only match once, multiple types are parsed elsewhere if (type.IsPlural) { continue; } clone.Matches.Clear(); clone.CurrentPosition = startPos; typePattern.Type = type.FinalTypeName; if (typePattern.ToString().Contains("%object")) { Debugger.Break(); } if (!RuntimeHelpers.TryEnsureSufficientExecutionStack()) { Debugger.Break(); } var result = typePattern.Parse(clone); if (result.IsSuccess) { var expression = new List <ParseMatch>(clone.Matches); if (expression.Count > 0) { possibleValues.Add((clone.CurrentPosition, expression, result)); } } } { //clone.ShouldJustCheckExpressionsThatMatchType = true; var expressions = WorkspaceManager.CurrentWorkspace.TypesManager.GetExpressionsThatCanFitType(KnownTypesManager .JavaLangObjectClass); if (expressions != null) { foreach (var expression in expressions) { foreach (var pattern in expression.PatternNodes) { if (pattern.ToString().Contains("ExprJavaCall")) { Debugger.Break(); } clone.Matches.Clear(); clone.CurrentPosition = startPos; clone.StartRangeMeasure(); var result = pattern.Parse(clone); if (!result.IsSuccess) { clone.UndoRangeMeasure(); continue; } var exprResult = clone.Matches; if (exprResult.Count > 0) { var cloneParseContext = clone.Clone(); result.Context = cloneParseContext; var expr = new SkriptExpression(expression, clone.EndRangeMeasure(), cloneParseContext); possibleValues.Add((clone.CurrentPosition, new List <ParseMatch>(new[] { new ExpressionParseMatch(expr, null) }), result)); } } } } } possibleValues.Sort((c1, c2) => - 1 * c1.CurrentPosition.CompareTo(c2.CurrentPosition)); if (possibleValues.Count <= 0) { return(null); } { var(lastPos, matches, _) = possibleValues[0]; ctx.ReadUntilPosition(lastPos); ctx.Properties.WrappedObjectCount--; return(new WrappedObject(matches)); } }