public static IDisposable SetDisposableBinding(this DependencyObject target, DependencyProperty dependencyProperty, Binding binding, bool restoreValue = false) { var localValue = target.ReadLocalValue(dependencyProperty); var weakRef = new WeakReference(target); BindingOperations.SetBinding(target, dependencyProperty, binding); return(DelegateDisposable.Create(delegate { var reference = weakRef.GetTarget <DependencyObject>(); if (reference == null) { return; } if (reference.ReadLocalBinding(dependencyProperty) != binding) { return; } if (restoreValue == false) { reference.ClearValue(dependencyProperty); } else { reference.RestoreLocalValue(dependencyProperty, localValue); } })); }
/// <summary> /// Invokes the <see cref="TraceSources"/> factory method with a delegate /// that adds a verbose console trace listener to all sources. /// </summary> /// <returns>Dispose to reset the default factory.</returns> public static IDisposable TraceAllVerbose() { void Configure(SimpleTraceSource traceSource) { traceSource.TraceSource.TryAdd( new Diagnostics.ConsoleTraceListener { Filter = new EventTypeFilter(SourceLevels.All), }); traceSource.TraceSource.Switch.Level = SourceLevels.All; } void Remove(SimpleTraceSource traceSource) => traceSource.TraceSource.Listeners.Remove(Diagnostics.ConsoleTraceListener.DefaultName); DelegateTraceSourceSelector selector = new DelegateTraceSourceSelector(Configure, Remove); TraceSources.AddSelector(selector); TraceSources.For(typeof(TestHelper)) .Verbose("TraceSources are verbose."); void Dispose() => TraceSources.RemoveSelector(selector); return(DelegateDisposable.With(Dispose)); }
public void ExplicitFinalizerTest() { /* * I referred to the following. * https://www.inversionofcontrol.co.uk/unit-testing-finalizers-in-csharp/ */ int managed = 0; int unmanaged = 0; WeakReference <DelegateDisposable> weak = null; Action exec = () => { var d = new DelegateDisposable(() => { managed += 1; }, () => { unmanaged += 1; }); d.Dispose(); weak = new WeakReference <DelegateDisposable>(d, true); }; exec(); GC.Collect(0, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(0, GCCollectionMode.Forced); managed.Is(1); unmanaged.Is(1); }
public IDisposable GetOrAdd <TScope, TService>( TScope scope, out TService service, out bool wasAdded, Func <TScope, TService> serviceFactory) { lock (registrations) { if (TryGet(scope, out service)) { wasAdded = false; return(DelegateDisposable.NoOp()); } service = serviceFactory(scope); if (service == null) { throw new ArgumentException( $"{nameof(service)} result is null for {typeof(TService).GetFriendlyFullName()}" + $" --- for scope '{scope}'.", nameof(serviceFactory)); } if (!registrations.TryGetValue(typeof(TScope), out Dictionary <object, object> scopes)) { scopes = new Dictionary <object, object>(8); registrations[typeof(TScope)] = scopes; } else { Debug.Assert(!scopes.ContainsKey(scope), "!scopes.ContainsKey(scope)"); } scopes[scope] = service; wasAdded = true; return(DelegateDisposable.With(scope, s => Remove(typeof(TScope), s))); } }
public void ImplicitFinalizerTest() { /* * I referred to the following. * https://www.inversionofcontrol.co.uk/unit-testing-finalizers-in-csharp/ */ int managed = 0; int unmanaged = 0; WeakReference <DelegateDisposable> weak = null; // define an instance of DelegateDisposable in inner method. Action exec = () => { var d = new DelegateDisposable(); d.DisposingAction = () => { managed += 1; }; d.UnmanagedDisposingAction = () => { unmanaged += 1; }; weak = new WeakReference <DelegateDisposable>(d, true); // I don't know why this WeakReference is neccesary... }; // execute test. exec(); // force GC. GC.Collect(0, GCCollectionMode.Forced); GC.WaitForPendingFinalizers(); GC.Collect(0, GCCollectionMode.Forced); // just to be sure managed.Is(0); unmanaged.Is(1); }
/// <summary> /// Sets application busy state with the specified status. /// </summary> /// <param name="status">A string describing the reason for the busy state.</param> /// <returns><see cref="System.IDisposable"/> instance which should /// be disposed upon exiting from the busy state.</returns> /// <remarks>This method is intended to be used with using statement. For example: /// <example><![CDATA[ /// using (WorkingStatusHelper.EnterBusyState("The application is currently Busy.")) /// { /// ... /// } /// ]]> /// </example> /// The application will leave busy state when the returned object has been disposed. /// </remarks> public static IDisposable EnterBusyState(string status) { var disposable = new DelegateDisposable(WorkingStatusHelper.SetReleased); WorkingStatusHelper.SetBusy(status); return(disposable); }
public virtual IDisposable WriteBlock(string text) { Info(FigletTransform.GetText(text)); return(DelegateDisposable.CreateBracket( () => Console.Title = $"Executing: {text}", () => Console.Title = $"Finished: {text}")); }
public void Ctor_NoDisposeCalled_DisposeActionNotCalled() { var actionCalled = false; var _ = new DelegateDisposable(() => actionCalled = true, true); Assert.False(actionCalled); }
private static IDisposable SwitchSecurityProtocol() { var previousProtocol = ServicePointManager.SecurityProtocol; return(DelegateDisposable.CreateBracket( () => ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12, () => ServicePointManager.SecurityProtocol = previousProtocol)); }
public static IDisposable GetTempDir(string folderName, out string tempDir) { tempDir = Path.Combine(Path.GetTempPath(), $"{typeof(MefComposerTests).GetFriendlyName()}.{folderName}"); string path = tempDir; void DisposeTempDir() { try { Directory.Delete(path, true); } catch { // Ignored } } DisposeTempDir(); try { Directory.CreateDirectory(tempDir); string GetDllPath(bool isDebug) { string result = new Uri(typeof(MefComposerTests).Assembly.CodeBase).LocalPath; result = Path.GetDirectoryName( Path.GetDirectoryName(Path.GetDirectoryName(Path.GetDirectoryName(result)))); // ReSharper disable once AssignNullToNotNullAttribute result = Path.Combine(Path.Combine(result, Helper.PartsProjectName), "bin"); result = Path.Combine( result, isDebug ? "Debug" : "Release"); return(Path.Combine(result, Helper.PartsProjectName + ".dll")); } bool useDebugPath = #if DEBUG true; #else false; #endif // ReSharper disable once ConditionIsAlwaysTrueOrFalse string partsPath = GetDllPath(useDebugPath); if (!File.Exists(partsPath)) { // ReSharper disable once ConditionIsAlwaysTrueOrFalse partsPath = GetDllPath(!useDebugPath); } File.Copy( partsPath, Path.Combine( tempDir, Helper.PartsProjectName + ".dll")); return(DelegateDisposable.With(DisposeTempDir)); } catch (Exception exception) { DisposeTempDir(); throw new AssertFailedException( $"Couldn't create temp assembly directory: {exception.Message}", exception); } }
public static IDisposable WriteBlock(this CustomFileWriter writer, string text) { return(DelegateDisposable .CreateBracket( () => writer.WriteLine(string.IsNullOrWhiteSpace(text) ? "{" : $"{text} {{"), () => writer.WriteLine("}")) .CombineWith(writer.Indent())); }
public void Dispose_Once_DisposeActionIsCalled() { var actionCalled = false; var d = new DelegateDisposable(() => actionCalled = true, true); d.Dispose(); Assert.True(actionCalled); }
private void WriteWithColors(string text, ConsoleColor foregroundColor) { var previousForegroundColor = Console.ForegroundColor; using (DelegateDisposable.CreateBracket( () => Console.ForegroundColor = foregroundColor, () => Console.ForegroundColor = previousForegroundColor)) { Console.WriteLine(text); } }
public void Dispose_TwiceWithOnlyDisposeOnceSet_DisposeActionIsCalledOnce() { var actionCalledCounter = 0; var d = new DelegateDisposable(() => actionCalledCounter++, true); d.Dispose(); d.Dispose(); Assert.Equal(1, actionCalledCounter); }
public void Dispose_Twice_DisposeActionIsCalledTwice() { var actionCalledCounter = 0; var d = new DelegateDisposable(() => actionCalledCounter++, false); d.Dispose(); d.Dispose(); Assert.Equal(2, actionCalledCounter); }
public void DelegateDisposable_Create() { int count = 0; var disposable = new DelegateDisposable(() => count = 1); Assert.NotNull(disposable); Assert.IsAssignableFrom <IDisposable>(disposable); disposable.Dispose(); Assert.Equal(1, count); }
/// <summary> /// Subscribe using weak reference. /// </summary> /// <typeparam name="T">A type of element issued from observation target.</typeparam> /// <param name="source">The observation target.</param> /// <param name="observer">The subscriber.</param> /// <returns>An instance of IDIsposable to unsubscribe.</returns> /// <remarks> /// When the reference of the IDisposable is lost without invoking Dispose(), /// subscription is unsubscribed automatically. /// </remarks> public static IDisposable WeakSubscribe <T>(this IObservable <T> source, IObserver <T> observer) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (observer == null) { throw new ArgumentNullException(nameof(observer)); } var outer = new DelegateDisposable(); var wref = new WeakReference <IDisposable>(outer); IDisposable inner = null; inner = source.Subscribe(new DelegateObserver <T>( onNext: v => { if (wref.TryGetTarget(out IDisposable d)) { observer.OnNext(v); } else { inner.Dispose(); } }, onError: e => { if (wref.TryGetTarget(out IDisposable d)) { observer.OnError(e); } else { inner.Dispose(); } }, onCompleted: () => { if (wref.TryGetTarget(out IDisposable d)) { observer.OnCompleted(); } else { inner.Dispose(); } })); outer.DisposingAction = inner.Dispose; return(outer); }
public void Disposing() { int i = 0; var d = new DelegateDisposable(); d.DisposingAction = () => { i++; }; d.Dispose(); i.Is(1); d.Dispose(); i.Is(1); }
public CapturedProcessStartInfo CaptureProcessStartInfo(Action action) { var fakeProcessManager = new CapturingProcessManager(); using (DelegateDisposable.CreateBracket( () => Instance = fakeProcessManager, () => Instance = this)) { action(); return(fakeProcessManager.CapturedProcessStartInfo); } }
IDisposable SwitchWorkingDirectory(string workingDirectory, bool allowCreate = true) { if (!Directory.Exists(workingDirectory)) { EnsureCleanDirectory(workingDirectory); } var previousWorkingDirectory = EnvironmentInfo.WorkingDirectory; return(DelegateDisposable.CreateBracket( () => Directory.SetCurrentDirectory(workingDirectory), () => Directory.SetCurrentDirectory(previousWorkingDirectory))); }
private void WriteWithColors(string text, ConsoleColor brightForeground, ConsoleColor darkForeground) { var previousForeground = Console.ForegroundColor; var backgroundColor = Console.BackgroundColor; var hasDarkBackground = backgroundColor == ConsoleColor.Black || backgroundColor.ToString().StartsWith("Dark"); using (DelegateDisposable.CreateBracket( () => Console.ForegroundColor = hasDarkBackground ? brightForeground : darkForeground, () => Console.ForegroundColor = previousForeground)) { Console.WriteLine(text); } }
/// <summary> /// Register event handler using weak reference event pattern. /// </summary> /// <typeparam name="TEventSupplier">A type of the object that exposes an event.</typeparam> /// <typeparam name="TDelegate">A type of the delegate that actual receive event.</typeparam> /// <param name="supplier">The object that exposes an event.</param> /// <param name="converter">A delegate that relays the event to an event handler that can not be registered directly.</param> /// <param name="addHandler">An Action to add event handler.</param> /// <param name="removeHandler">An Action to remove event handler.</param> /// <param name="handler">An event handler.</param> /// <returns>An instance of IDIsposable to unsubscribe.</returns> public static IDisposable WeakSubscribe <TEventSupplier, TEventArgs, TDelegate>( this TEventSupplier supplier, Func <TDelegate, EventHandler <TEventArgs> > converter, Action <TEventSupplier, EventHandler <TEventArgs> > addHandler, Action <TEventSupplier, EventHandler <TEventArgs> > removeHandler, TDelegate handler) { if (supplier == null) { throw new ArgumentNullException(nameof(supplier)); } if (converter == null) { throw new ArgumentNullException(nameof(converter)); } if (addHandler == null) { throw new ArgumentNullException(nameof(addHandler)); } if (removeHandler == null) { throw new ArgumentNullException(nameof(removeHandler)); } if (handler == null) { throw new ArgumentNullException(nameof(handler)); } var inner = new DelegateDisposable(); var outer = new DelegateDisposable(); var wref = new WeakReference <IDisposable>(outer); void relayHandler(object s, TEventArgs e) { if (wref.TryGetTarget(out IDisposable d)) { converter(handler)(s, e); } else { inner.Dispose(); } } addHandler(supplier, relayHandler); inner.DisposingAction = () => removeHandler(supplier, relayHandler); outer.DisposingAction = inner.Dispose; return(outer); }
public async void DisposingMulti() { int i = 0; var d = new DelegateDisposable(() => { i++; }); List <Task> tasks = new List <Task>(); for (int j = 0; j < 10; j++) { tasks.Add(Task.Run(() => d.Dispose())); } await Task.WhenAll(tasks); i.Is(1); }
public virtual IDisposable WriteBlock(string text) { return(DelegateDisposable.CreateBracket( () => { var formattedBlockText = FormatBlockText(text) .Split(new[] { EnvironmentInfo.NewLine }, StringSplitOptions.None); Console.WriteLine(); Console.WriteLine("╬" + new string(c: '═', text.Length + 5)); formattedBlockText.ForEach(x => Console.WriteLine($"║ {x}")); Console.WriteLine("╬" + new string(c: '═', Math.Max(text.Length - 4, 2))); Console.WriteLine(); })); }
protected internal virtual IDisposable WriteBlock(string text) { return(DelegateDisposable.CreateBracket( () => { var formattedBlockText = text .Split(new[] { EnvironmentInfo.NewLine }, StringSplitOptions.None) .Select(Theme.FormatInformation); Debug(); Debug("╬" + new string(c: '═', text.Length + 5)); formattedBlockText.ForEach(x => Debug($"║ {x}")); Debug("╬" + new string(c: '═', Math.Max(text.Length - 4, 2))); Debug(); })); }
public IDisposable BeginScope <TState>(TState state) { var oldScope = _scope; var disposable = new DelegateDisposable <TState>(() => { _scope = oldScope; }); _scope = state; _sink.Begin(new BeginScopeContext() { LoggerName = _name, Scope = state, }); return(disposable); }
/// <summary> /// Tries to enter the reader lock, and creates a disposable object that exits the lock /// when disposed. /// </summary> /// <param name="gotLock">Will be false if your attempt to acquire the lock fails: if false /// then you do not have the lock.</param> /// <param name="millisecondsTimeout">Optional timeout to wait for the lock. Notice that the /// defult is not infinite: you may pass <see cref="Timeout.Infinite"/>.</param> /// <param name="cancellationToken">Optional token that will cancel the wait for the lock.</param> /// <returns>Not null.</returns> public IDisposable WithReaderLock( out bool gotLock, int millisecondsTimeout = 1000 * 60 * 3, CancellationToken cancellationToken = default) { DelegateDisposable <bool> result = DelegateDisposable.With( () => enter(millisecondsTimeout, cancellationToken, false), isGotLock => { if (isGotLock) { exit(false); } }); gotLock = result.State; return(result); }
internal override IDisposable WriteBlock(string text) { var stopWatch = new Stopwatch(); return(DelegateDisposable.CreateBracket( () => { _teamCity.OpenBlock(text); stopWatch.Start(); }, () => { _teamCity.CloseBlock(text); _teamCity.AddStatisticValue( $"NUKE_DURATION_{text.SplitCamelHumpsWithSeparator("_").ToUpper()}", stopWatch.ElapsedMilliseconds.ToString()); stopWatch.Stop(); })); }
/// <summary> /// Ensures that the directory exists, and returns a disposable /// that will delete the directory and all files. /// </summary> /// <param name="folderPath">Required.</param> /// <returns>Not null.</returns> public static IDisposable UsingTempFolder(string folderPath) { if (!Directory.Exists(folderPath)) { Directory.CreateDirectory(folderPath); } void DeleteTempFolder() { if (!Directory.Exists(folderPath)) { return; } try { Directory.Delete(folderPath, true); } catch { // The folder may be open in Explorer } } return(DelegateDisposable.With(DeleteTempFolder)); }
/// <summary> /// Subscribe using "very" weak reference. /// </summary> /// <typeparam name="T">A type of element issued from observation target.</typeparam> /// <param name="source">The observation target.</param> /// <param name="observer">The subscriber.</param> /// <returns>An instance of IDIsposable to unsubscribe.</returns> /// <remarks> /// When the reference of the IDisposable or observer's own reference is lost without invoking Dispose(), /// subscription is unsubscribed automatically. /// </remarks> public static IDisposable VeryWeakSubscribe <T>(this IObservable <T> source, IObserver <T> observer) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (observer == null) { throw new ArgumentNullException(nameof(observer)); } var outer = new DelegateDisposable(); var wref = new WeakReference <IDisposable>(outer); var wo = new WeakReference <IObserver <T> >(observer); IDisposable inner = null; inner = source.Subscribe(new DelegateObserver <T>( onNext: v => { if (wref.TryGetTarget(out IDisposable d) && wo.TryGetTarget(out IObserver <T> o)) { o.OnNext(v); }