public static LifetimeDefinition Define(OuterLifetime lifetime, [CanBeNull] string id = null, [CanBeNull][InstantHandle] Action <LifetimeDefinition, Lifetime> atomicAction = null) { lifetime.AssertNotNull(); // Fallback to defaults if (String.IsNullOrEmpty(id)) { id = LifetimeDefinition.AnonymousLifetimeId; } // var nested = new LifetimeDefinition(id, 0, logger ?? Log.Root); var nested = new LifetimeDefinition { Id = id } /*{ Logger = logger ?? Log.Root }*/; try { // Atomic init on the new lifetime atomicAction?.Invoke(nested, nested.Lifetime); // Attach as nested to the parent lifetime // if(!nested.IsTerminated) // Might have been terminated by FAtomic lifetime.Def.Attach(nested); // Pass True: might be terminated async on another thread between our check and AttachNested body (example: Queue from another thread) } catch { nested.Terminate(); throw; } return(nested); }
/// <summary> /// <para>Scopes your code in <paramref name="action" /> with a lifetime that is terminated automatically when <paramref name="action" /> completes execution, or when its execution is aborted by an exception.</para> /// <para>Analogous to the <c>using</c> statement of the C# language on everything that is added to the lifetime.</para> /// </summary> /// <param name="parent">A parent lifetime which limits the lifetime given to your action, and migth terminate it before the action ends.</param> /// <param name="action">The code to execute with a temporary lifetime.</param> public static async Task <T> UsingAsync <T>(OuterLifetime parent, [NotNull][InstantHandle] Func <Lifetime, Task <T> > action) { if (action == null) { throw new ArgumentNullException(nameof(action)); } using (var def = new LifetimeDefinition()) { parent.Def.Attach(def); return(await action(def.Lifetime)); } }