protected override void Dispose(bool disposing) { base.Dispose(disposing); if (!Nested) { if (!_completed) { try { if (_readOnly) { ScopeData.Commit(); } else { ScopeData.Rollback(); } } catch (Exception e) { _exceptionHandler?.HandleException(e); } } _completed = true; ScopeData.Dispose(); } }
/// <summary> /// Helper for managing cancellation, Timeout and result creation. /// </summary> protected virtual async MorestachioDocumentResultPromise Render(object data, CancellationToken token, CompilationAsync executer, IByteCounterStream targetStream) { PreRender(); var timeoutCancellation = new CancellationTokenSource(); if (ParserOptions.Timeout != TimeSpan.Zero) { timeoutCancellation.CancelAfter(ParserOptions.Timeout); var anyCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(token, timeoutCancellation.Token); token = anyCancellationToken.Token; } PerformanceProfiler profiler = null; using (var byteCounterStream = targetStream ?? ParserOptions.StreamFactory.GetByteCounterStream(ParserOptions)) { var context = ParserOptions.CreateContextObject("", data); var scopeData = new ScopeData(ParserOptions, token); try { if (ParserOptions.ProfileExecution) { scopeData.Profiler = profiler = new PerformanceProfiler(true); } await executer(byteCounterStream, context, scopeData); if (timeoutCancellation.IsCancellationRequested) { throw new TimeoutException( $"The requested timeout of '{ParserOptions.Timeout:g}' for template generation was reached."); } PostRender(); } finally { if (!CaptureVariables) { scopeData.Dispose(); scopeData.Variables.Clear(); } } return(new MorestachioDocumentResult(byteCounterStream, profiler, scopeData.Variables.ToDictionary(e => e.Key, e => scopeData.GetFromVariable(null, e.Value)?.Value))); } }
/// <summary> /// 在指定的范围内使用工作单元 /// 最外层的工作单元负责创建和销毁数据 /// </summary> /// <returns></returns> public IDisposable Scope() { var isRootUow = Data.Value == null; if (isRootUow) { var data = new ScopeData(); Data.Value = data; return(new SimpleDisposable(() => { data.Dispose(); Data.Value = null; })); } return(new SimpleDisposable(() => { })); }