Skip to content

Commit

Permalink
Added EnsureExtensions for IDisposable objects.
Browse files Browse the repository at this point in the history
Disposing logic reorganized.
Now all exceptions correctly ignored.
Closes #1, closes #5 and closes #6.
Version 0.0.2.
  • Loading branch information
Konard committed Jul 25, 2019
1 parent 9abd4bc commit d52fc95
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 45 deletions.
5 changes: 3 additions & 2 deletions Disposable.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using Platform.Exceptions;

namespace Platform.Disposables
{
Expand Down Expand Up @@ -46,10 +47,10 @@ public static bool TryDispose<T>(ref T @object)
}
}
}
catch (Exception)
catch (Exception exception)
{
exception.Ignore();
}

return false;
}

Expand Down
70 changes: 40 additions & 30 deletions DisposableBase.cs
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading;
using Platform.Exceptions;

namespace Platform.Disposables
{
/// <summary>
/// Provides a base implementation for IDisposable interface with the basic logic necessary to increase the likelihood of correct memory release.
/// Предоставляет базовую реализацию для интерфейса IDisposable с основной логикой необходимой для повышения вероятности корректного высвобождения памяти.
/// Provides a base implementation for IDisposable interface with the basic logic necessary to increase the likelihood of correct unmanaged resources release.
/// Предоставляет базовую реализацию для интерфейса IDisposable с основной логикой необходимой для повышения вероятности корректного высвобождения неуправляемых ресурсов.
/// </summary>
/// <remarks>
/// TODO: Попробовать реализовать компилируемый автоматический вариант DisposeCore (находить все типы IDisposable, IDisposal и автоматически вычищать их).
/// </remarks>
public abstract class DisposableBase : IDisposable
{
private static readonly Process CurrentProcess = Process.GetCurrentProcess();
Expand Down Expand Up @@ -40,8 +37,17 @@ public void Dispose()

public void Destruct()
{
if (!IsDisposed)
Dispose(false);
try
{
if (!IsDisposed)
{
Dispose(false);
}
}
catch (Exception exception)
{
exception.Ignore();
}
}

private void OnProcessExit(object sender, EventArgs e)
Expand All @@ -56,37 +62,41 @@ private void Dispose(bool manual)
{
var originalDisposedValue = Interlocked.CompareExchange(ref _disposed, 1, 0);
var wasDisposed = originalDisposedValue > 0;

if (!wasDisposed)
{
TryUnsubscribeFromProcessExitedEvent();
}
if (!AllowMultipleDisposeCalls && manual)
{
Ensure.Always.NotDisposed(this, ObjectName, "Multiple dispose calls are now allowed. Override AllowMultipleDisposeCalls property to modify behaviour.");
}
if (AllowMultipleDisposeAttempts || !wasDisposed)
{
try
{
if (!wasDisposed)
{
if (CurrentProcess != null)
CurrentProcess.Exited -= OnProcessExit;
//else
// Process.GetCurrentProcess().Exited -= OnProcessExit;
}
DisposeCore(manual, wasDisposed);
}
}

DisposeCore(manual, wasDisposed);
private bool TryUnsubscribeFromProcessExitedEvent()
{
try
{
if (CurrentProcess != null)
{
CurrentProcess.Exited -= OnProcessExit;
}
catch (Exception)
else
{
if (!AllowMultipleDisposeAttempts || manual) throw;
Process.GetCurrentProcess().Exited -= OnProcessExit;
}
return true;
}
catch (Exception exception)
{
exception.Ignore();
return false;
}
else if (!AllowMultipleDisposeCalls && manual)
throw new ObjectDisposedException(ObjectName);
}

protected abstract void DisposeCore(bool manual, bool wasDisposed);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
protected virtual void EnsureNotDisposed()
{
if (_disposed > 0)
throw new ObjectDisposedException(ObjectName);
}
}
}
2 changes: 1 addition & 1 deletion Disposable[T].cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ namespace Platform.Disposables
{
public partial class Disposable<T> : Disposable
{
public readonly T Object;
protected readonly T Object;

public Disposable(T @object) => Object = @object;

Expand Down
44 changes: 44 additions & 0 deletions EnsureExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using Platform.Exceptions;

#pragma warning disable IDE0060 // Remove unused parameter

namespace Platform.Disposables
{
public static class EnsureExtensions
{
#region Always

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void NotDisposed(this EnsureAlwaysExtensionRoot root, IDisposable disposable) => NotDisposed(root, disposable, null, null);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void NotDisposed(this EnsureAlwaysExtensionRoot root, IDisposable disposable, string objectName) => NotDisposed(root, disposable, objectName, null);

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void NotDisposed(this EnsureAlwaysExtensionRoot root, IDisposable disposable, string objectName, string message)
{
if (disposable.IsDisposed)
{
throw new ObjectDisposedException(objectName, message);
}
}

#endregion

#region OnDebug

[Conditional("DEBUG")]
public static void NotDisposed(this EnsureOnDebugExtensionRoot root, IDisposable disposable) => Ensure.Always.NotDisposed(disposable, null, null);

[Conditional("DEBUG")]
public static void NotDisposed(this EnsureOnDebugExtensionRoot root, IDisposable disposable, string objectName) => Ensure.Always.NotDisposed(disposable, objectName, null);

[Conditional("DEBUG")]
public static void NotDisposed(this EnsureOnDebugExtensionRoot root, IDisposable disposable, string objectName, string message) => Ensure.Always.NotDisposed(disposable, objectName, message);

#endregion
}
}
8 changes: 4 additions & 4 deletions IDisposable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ public interface IDisposable : System.IDisposable
bool IsDisposed { get; }

/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// Выполняет определенные пользователем задачи, связанные с освобождением, высвобождением или сбросом неуправляемых ресурсов.
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources without throwing any exceptions.
/// Выполняет определенные пользователем задачи, связанные с освобождением, высвобождением или сбросом неуправляемых ресурсов без выбрасывания исключений.
/// </summary>
/// <remarks>
/// Should be called only from classes destructors.
/// Должен вызываться только из деструкторов классов.
/// Should be called only from classes destructors, or in case exceptions should be not thrown.
/// Должен вызываться только из деструкторов классов, или в случае, если исключения выбрасывать нельзя.
/// </remarks>
void Destruct();
}
Expand Down
12 changes: 10 additions & 2 deletions Platform.Disposables.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
<AssemblyName>Platform.Disposables</AssemblyName>
<PackageId>Platform.Disposables</PackageId>
<PackageTags>Disposable;DisposableBase;Disposables;IDisposable</PackageTags>
<PackageIconUrl>https://raw.githubusercontent.com/LinksPlatform/Documentation/master/doc/Avatar-rainbow.png</PackageIconUrl>
<PackageIconUrl>https://raw.githubusercontent.com/linksplatform/Documentation/18469f4d033ee9a5b7b84caab9c585acab2ac519/doc/Avatar-rainbow-icon-64x64.png</PackageIconUrl>
<PackageProjectUrl>https://github.com/linksplatform/Disposables</PackageProjectUrl>
<PackageLicenseUrl>https://github.com/linksplatform/Disposables/blob/master/LICENSE</PackageLicenseUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<RepositoryType>git</RepositoryType>
<RepositoryUrl>git://github.com/linksplatform/Disposables</RepositoryUrl>
Expand All @@ -21,6 +21,14 @@
<GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
<IncludeSymbols>true</IncludeSymbols>
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
<PackageReleaseNotes>Added EnsureExtensions for IDisposable objects.
Disposing logic reorganized.
Now all exceptions correctly ignored.
Closes three issues.</PackageReleaseNotes>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Platform.Exceptions" Version="0.1.0" />
</ItemGroup>

</Project>
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

# Disposables ([русская версия](https://github.com/LinksPlatform/Disposables/blob/master/README.ru.md))

Forked from: https://github.com/Konard/LinksPlatform/tree/708f6143645333781adae0cad7ae998fefcd6317/Platform/Platform.Helpers/Disposables
Forked from: [Konard/LinksPlatform/Platform/Platform.Helpers/Disposables](https://github.com/Konard/LinksPlatform/tree/708f6143645333781adae0cad7ae998fefcd6317/Platform/Platform.Helpers/Disposables)

Namespace: Platform.Disposables

Package at NuGet: https://www.nuget.org/packages/Platform.Disposables
Package at NuGet: [Platform.Disposables](https://www.nuget.org/packages/Platform.Disposables)

## Examples

Expand Down Expand Up @@ -46,4 +46,4 @@ namespace Examples
}
}
}
```
```
6 changes: 3 additions & 3 deletions README.ru.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

# Disposables ([english version](https://github.com/LinksPlatform/Disposables/blob/master/README.md))

Ответвление от: https://github.com/Konard/LinksPlatform/tree/708f6143645333781adae0cad7ae998fefcd6317/Platform/Platform.Helpers/Disposables
Ответвление от: [Konard/LinksPlatform/Platform/Platform.Helpers/Disposables](https://github.com/Konard/LinksPlatform/tree/708f6143645333781adae0cad7ae998fefcd6317/Platform/Platform.Helpers/Disposables)

Пространство имён: Platform.Disposables

Пакет в NuGet: https://www.nuget.org/packages/Platform.Disposables
Пакет в NuGet: [Platform.Disposables](https://www.nuget.org/packages/Platform.Disposables)

## Примеры

Expand Down Expand Up @@ -46,4 +46,4 @@ namespace Examples
}
}
}
```
```

0 comments on commit d52fc95

Please sign in to comment.