মূলত আপনি যে URL টি হিট করতে চান তার জন্য একটি ক্রিয়া বা টাস্ক তৈরি করতে চান, তাদের একটি তালিকায় রাখুন এবং তারপরে সেই তালিকাটি প্রক্রিয়া করুন, যে সংখ্যাটি সমান্তরালভাবে প্রক্রিয়াজাত হতে পারে সীমাবদ্ধ করে।
আমার ব্লগ পোস্টটি দেখায় যে কীভাবে এটি টাস্ক এবং ক্রিয়াগুলি সহ উভয়ই করা যায় এবং একটি নমুনা প্রকল্প সরবরাহ করে যা আপনি ডাউনলোড এবং চালিয়ে যেতে পারেন উভয়কে ক্রিয়াতে দেখতে।
ক্রিয়া সহ
অ্যাকশনগুলি ব্যবহার করে, আপনি অন্তর্নির্মিত। নেট সমান্তরাল ব্যবহার করতে পারেন n এখানে আমরা এটিকে সমান্তরালভাবে প্রায় 20 টি থ্রেডে চালিত করতে সীমাবদ্ধ করি।
var listOfActions = new List<Action>();
foreach (var url in urls)
{
var localUrl = url;
// Note that we create the Task here, but do not start it.
listOfTasks.Add(new Task(() => CallUrl(localUrl)));
}
var options = new ParallelOptions {MaxDegreeOfParallelism = 20};
Parallel.Invoke(options, listOfActions.ToArray());
টাস্ক সহ
টাস্ক সহ কোনও বিল্ট-ইন ফাংশন নেই। তবে, আমি আমার ব্লগে যেটি সরবরাহ করি তা আপনি ব্যবহার করতে পারেন।
/// <summary>
/// Starts the given tasks and waits for them to complete. This will run, at most, the specified number of tasks in parallel.
/// <para>NOTE: If one of the given tasks has already been started, an exception will be thrown.</para>
/// </summary>
/// <param name="tasksToRun">The tasks to run.</param>
/// <param name="maxTasksToRunInParallel">The maximum number of tasks to run in parallel.</param>
/// <param name="cancellationToken">The cancellation token.</param>
public static async Task StartAndWaitAllThrottledAsync(IEnumerable<Task> tasksToRun, int maxTasksToRunInParallel, CancellationToken cancellationToken = new CancellationToken())
{
await StartAndWaitAllThrottledAsync(tasksToRun, maxTasksToRunInParallel, -1, cancellationToken);
}
/// <summary>
/// Starts the given tasks and waits for them to complete. This will run the specified number of tasks in parallel.
/// <para>NOTE: If a timeout is reached before the Task completes, another Task may be started, potentially running more than the specified maximum allowed.</para>
/// <para>NOTE: If one of the given tasks has already been started, an exception will be thrown.</para>
/// </summary>
/// <param name="tasksToRun">The tasks to run.</param>
/// <param name="maxTasksToRunInParallel">The maximum number of tasks to run in parallel.</param>
/// <param name="timeoutInMilliseconds">The maximum milliseconds we should allow the max tasks to run in parallel before allowing another task to start. Specify -1 to wait indefinitely.</param>
/// <param name="cancellationToken">The cancellation token.</param>
public static async Task StartAndWaitAllThrottledAsync(IEnumerable<Task> tasksToRun, int maxTasksToRunInParallel, int timeoutInMilliseconds, CancellationToken cancellationToken = new CancellationToken())
{
// Convert to a list of tasks so that we don't enumerate over it multiple times needlessly.
var tasks = tasksToRun.ToList();
using (var throttler = new SemaphoreSlim(maxTasksToRunInParallel))
{
var postTaskTasks = new List<Task>();
// Have each task notify the throttler when it completes so that it decrements the number of tasks currently running.
tasks.ForEach(t => postTaskTasks.Add(t.ContinueWith(tsk => throttler.Release())));
// Start running each task.
foreach (var task in tasks)
{
// Increment the number of tasks currently running and wait if too many are running.
await throttler.WaitAsync(timeoutInMilliseconds, cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
task.Start();
}
// Wait for all of the provided tasks to complete.
// We wait on the list of "post" tasks instead of the original tasks, otherwise there is a potential race condition where the throttler's using block is exited before some Tasks have had their "post" action completed, which references the throttler, resulting in an exception due to accessing a disposed object.
await Task.WhenAll(postTaskTasks.ToArray());
}
}
এবং তারপরে আপনার কার্যগুলির তালিকা তৈরি করুন এবং ফাংশনটি চালানোর জন্য কল করুন, একবারে সর্বোচ্চ 20 একসাথে বলে, আপনি এটি করতে পারেন:
var listOfTasks = new List<Task>();
foreach (var url in urls)
{
var localUrl = url;
// Note that we create the Task here, but do not start it.
listOfTasks.Add(new Task(async () => await CallUrl(localUrl)));
}
await Tasks.StartAndWaitAllThrottledAsync(listOfTasks, 20);