Search
 
SCRIPT & CODE EXAMPLE
 

CSHARP

dispose await task c#

public interface ITrackingDisposable : IDisposable, IAsyncDisposable
{
    Task FinishDisposeAsync();
}

public class TrackingDisposer : IDisposable, IAsyncDisposable
{
    private readonly LinkedList<Task> _tasks = new LinkedList<Task>();

    private readonly ITrackingDisposable _target;

    private readonly TaskCompletionSource<object> _disposing = new TaskCompletionSource<object>();

    public bool IsDisposed { get; private set; } = false;

    public TrackingDisposer(ITrackingDisposable target)
    => _target = target ?? throw new ArgumentNullException();

    public bool Track(Func<Task> func, out Task result)
    {
        lock (_tasks)
        {
            if (IsDisposed)
            {
                result = null;
                return false;
            }

            var task = func();
            var node = _tasks.AddFirst(task);

            async Task ending()
            {
                await task;
                var dispose = false;
                lock (_tasks)
                {
                    _tasks.Remove(node);
                    dispose = IsDisposed && _tasks.Count == 0;
                }
                if (dispose)
                {
                    await _target.FinishDisposeAsync();
                    _disposing.SetResult(null);
                }
            }

            result = ending();
        }
        return true;
    }

    public bool Track<TResult>(Func<Task<TResult>> func, out Task<TResult> result)
    {
        lock (_tasks)
        {
            if (IsDisposed)
            {
                result = null;
                return false;
            }

            var task = func();
            var node = _tasks.AddFirst(task);

            async Task<TResult> ending()
            {
                var result = await task;
                var dispose = false;
                lock (_tasks)
                {
                    _tasks.Remove(node);
                    dispose = IsDisposed && _tasks.Count == 0;
                }
                if (dispose)
                {
                    await _target.FinishDisposeAsync();
                    _disposing.SetResult(null);
                }
                return result;
            }

            result = ending();
        }
        return true;
    }

    public void Dispose()
    {
        var dispose = false;

        lock (_tasks)
        {
            if (IsDisposed)
            {
                return;
            }

            IsDisposed = true;
            dispose = _tasks.Count == 0;
        }

        if (dispose)
        {
            _target.FinishDisposeAsync();
            _disposing.SetResult(null);
        }
    }

    public ValueTask DisposeAsync()
    {
        Dispose();
        return new ValueTask(_disposing.Task);
    }
}

public abstract class TrackingDisposable : ITrackingDisposable
{
    private readonly TrackingDisposer _disposer;

    public TrackingDisposable()
    => _disposer = new TrackingDisposer(this);

    protected virtual void FinishDispose() { }

    protected virtual Task FinishDisposeAsync()
    => Task.CompletedTask;

    Task ITrackingDisposable.FinishDisposeAsync()
    {
        FinishDispose();
        return FinishDisposeAsync();
    }

    public void Dispose()
    => _disposer.Dispose();

    public ValueTask DisposeAsync() => _disposer.DisposeAsync();

    protected Task Track(Func<Task> func)
    => _disposer.Track(func, out var result)
        ? result
        : throw new ObjectDisposedException(nameof(TrackingDisposable));

    protected Task<TResult> Track<TResult>(Func<Task<TResult>> func)
    => _disposer.Track(func, out var result)
        ? result
        : throw new ObjectDisposedException(nameof(TrackingDisposable));
}
Comment

PREVIOUS NEXT
Code Example
Csharp :: PasswordBox Helper 
Csharp :: c# how to use or operator on integers in while loop 
Csharp :: xunit setup throw exception 
Csharp :: c# get the return value of a func 
Csharp :: serenity.is get entity columns as ienumerable string 
Csharp :: c# check if pdf is protected without password 
Csharp :: lambda distinct by property 
Csharp :: unrecognized escape sequence c# connection string 
Csharp :: Min max to 01 
Csharp :: wpf repository pattern query async with includes properties 
Csharp :: c# alert message 
Csharp :: c# silent execute exe 
Csharp :: cefsharp not passing keydown to form 
Csharp :: youtube unity 2d intercept 
Csharp :: Destroy(GameObject.Find("Turret_Laser_Hit"), 0.2f); 
Csharp :: c# order by descending on 2 values 
Csharp :: Strings build-in functions in c# 
Csharp :: winforms lifecycle 
Csharp :: c# hardcode datetime quoting 
Csharp :: using randomly chars to build a string 
Csharp :: c# initialize event 
Csharp :: binaural generator 
Csharp :: 110771 
Csharp :: c# how to convert string to float 
Csharp :: unity I run exe second monitor 
Csharp :: Find Center Of Transforms, Points, Multiple Objects 
Csharp :: encode < for xml 
Csharp :: initialization of dictionary in other forms c# 
Csharp :: unity run all interfaces 
Csharp :: esaddex34 
ADD CONTENT
Topic
Content
Source link
Name
5+5 =