网上演练
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
3.0 KiB

#if FAT
using System;
using System.Threading;
using LinqInternal.Core;
namespace LinqInternal.Threading
{
[System.Diagnostics.DebuggerNonUserCode]
internal sealed class DisposableAkin :
#if !NETCOREAPP1_1
System.Runtime.ConstrainedExecution.CriticalFinalizerObject,
#endif
IDisposable
{
private Action _release;
private Thread _thread;
private DisposableAkin(Action release, Thread thread)
{
if (release == null)
{
throw new ArgumentNullException("release");
}
if (thread == null)
{
throw new ArgumentNullException("thread");
}
_release = release;
_thread = thread;
}
~DisposableAkin()
{
try
{
// Empty
}
finally
{
try
{
Dispose(false);
}
catch (Exception exception)
{
// Catch'em all - fields may be partially collected.
GC.KeepAlive(exception);
}
}
}
public bool IsDisposed
{
get { return _thread == null; }
}
public static DisposableAkin Create(Action release)
{
return new DisposableAkin(release, Thread.CurrentThread);
}
public static DisposableAkin Create()
{
return new DisposableAkin(ActionHelper.GetNoopAction(), Thread.CurrentThread);
}
public bool Dispose(Func<bool> condition)
{
if (condition == null)
{
throw new ArgumentNullException("condition");
}
if (ReferenceEquals(Interlocked.CompareExchange(ref _thread, null, Thread.CurrentThread), Thread.CurrentThread))
{
if (condition.Invoke())
{
try
{
_release.Invoke();
return true;
}
finally
{
_release = null;
}
}
return false;
}
return false;
}
public void Dispose()
{
try
{
Dispose(true);
}
finally
{
GC.SuppressFinalize(this);
}
}
private void Dispose(bool disposeManagedResources)
{
if
(
!disposeManagedResources
|| ReferenceEquals(Interlocked.CompareExchange(ref _thread, null, Thread.CurrentThread), Thread.CurrentThread)
)
{
try
{
_release.Invoke();
}
finally
{
_release = null;
}
}
}
}
}
#endif