uniblab icon

poor man's way of limiting concurrency with PTL

uniblab | PRO | 04/10/20 07:41:57 PM UTC | 0 ⭐ | 1574 👁️ | Never ⏰ | []
C# |

2.03 KB

|

None

|

0 👍

/

0 👎

public void DoWork( WorkOrder workOrder ) {
    this.WorkOrder = workOrder ?? throw new System.ArgumentNullException( "workOrder" );
    var steps = ( this.Steps ?? new IStep[ 0 ] ).OfType<IStep>();
    if ( !steps.Any() ) {
        return;
    }
    using ( var tokenSource = new System.Threading.CancellationTokenSource() ) {
        var token = tokenSource.Token;
        var maxP = this.MaxDegreeOfParallelism;
        if ( DefaultMaxDegreeOfParallelism == maxP ) {
            this.DoUnlimitedWork( workOrder, steps, token );
        } else {
            this.DoLimitedWork( workOrder, steps, token, maxP );
        }
    }
}
private void DoUnlimitedWork( WorkOrder workOrder, System.Collections.Generic.IEnumerable<IStep> steps, System.Threading.CancellationToken token ) {
    System.Collections.Generic.ICollection<System.Threading.Tasks.Task> tasks = new System.Collections.Generic.List<System.Threading.Tasks.Task>();
    var factory = new System.Threading.Tasks.TaskFactory(
        token,
        System.Threading.Tasks.TaskCreationOptions.LongRunning,
        System.Threading.Tasks.TaskContinuationOptions.LongRunning,
        System.Threading.Tasks.TaskScheduler.Default
    );
    foreach ( var step in steps ) {
        tasks.Add( factory.StartNew(
            () => step.DoWork( workOrder ),
            token
        ) );
    }
    System.Threading.Tasks.Task.WaitAll( tasks.ToArray(), token );
}
private void DoLimitedWork( WorkOrder workOrder, System.Collections.Generic.IEnumerable<IStep> steps, System.Threading.CancellationToken token, System.Int32 MaxDegreeOfParallelism ) {
    using ( var semaphore = new Semaphore( this.MaxDegreeOfParallelism, this.MaxDegreeOfParallelism ) ) {
        System.Collections.Generic.ICollection<System.Threading.Tasks.Task> tasks = new System.Collections.Generic.List<System.Threading.Tasks.Task>();
        var factory = new System.Threading.Tasks.TaskFactory( token );
        foreach ( var step in steps ) {
            tasks.Add( factory.StartNew(
                () => {
                    semaphore.Wait();
                    step.DoWork( workOrder );
                    semaphore.Release();
                },
                token
            ) );
        }
        System.Threading.Tasks.Task.WaitAll( tasks.ToArray(), token );
    }
}

Comments