.NET Fiddle

CSharp · Console

/Program.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;

public class Program
{
	private static readonly SemaphoreSlim _sem = new SemaphoreSlim(3, 3);
	private static readonly Random _r = new Random();
	private static long _counter = 0;
	public static IPAddress RandomIpAddress()
	{
		var data = new byte[4];
		_r.NextBytes(data);
		return new IPAddress(data);
	}

	public static async Task<PingReply> SomethingAsync(IPAddress address)
	{
		try
		{
			Interlocked.Increment(ref _counter);
			var ping = new Ping();
			var result = await ping.SendPingAsync(address, 1000);
			Console.WriteLine($"{Interlocked.Read(ref _counter)} : {address} - {result.Status} {result.RoundtripTime}ms");
			return result;
		}
		catch (PingException ex)
		{
			Console.WriteLine($"{Interlocked.Read(ref _counter)} : {address} - {ex.Message}");
		}
		finally
		{
			Interlocked.Decrement(ref _counter);
		}

		return null;
	}

	public static async Task Test1(IEnumerable<IPAddress> list)
	{
		static async Task<PingReply> Process(IPAddress address)
		{
			try
			{
				await _sem.WaitAsync();
				return await SomethingAsync(address);
			}
			finally
			{
				_sem.Release();
			}
		}

		await Task.WhenAll(list.Select(Process));
	}

	public static async Task Test2(IEnumerable<IPAddress> list)
	{
		var block = new ActionBlock<IPAddress>(SomethingAsync, new ExecutionDataflowBlockOptions(){MaxDegreeOfParallelism = 3});
		await Task.WhenAll(list.Select(x => block.SendAsync(x)));
		block.Complete();
		await block.Completion;
	}

	static async Task Main()
	{
		// a list of something
		var list = Enumerable.Range(0, 12).Select(x => RandomIpAddress()).ToList();
		await Test1(list);
		Console.WriteLine("---------");
		await Test2(list);
	}
}
;