I have a function that needs to process items 3 at a time, and if the total time taken is less than x seconds, the thread should sleep for the remaining seconds before proceeding further.
So I'm doing the following:
private void ProcessItems()
{
for (int i = 0, n = items.Count; i < n; i++)
{
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
batch.Add(items[i]);
if (batch.Count == 3 || i >= items.Count - 3)
{
List<Task> tasks = new List<Task>(3);
foreach (Item item in batch)
tasks.Add(Task.Factory.StartNew(() => ProcessItem(item)));
Task.WaitAll(tasks.ToArray());
batch.Clear();
}
stopwatch.Stop();
int elapsed = (int)stopwatch.ElapsedMilliseconds;
int delay = (3000) - elapsed;
if (delay > 0)
Thread.Sleep(delay);
}
}
The ProcessItem function makes a webrequest and processes the response (callback). This is the function that takes a small amount of time.
However, if I understand tasks correctly, a thread can have multiple tasks. Therefore, if I sleep the thread, other tasks can be affected.
Is there a more efficient way to achieve the above, and can tasks be used within Parallel.Foreach?
Tasks run on automatically managed threads. There is nothing intrinsically wrong with blocking a thread. It is just a little wasteful.
Here is how I would implement this very cleanly:
MyItem[] items = ...;
foreach(MyItem[] itemsChunk in items.AsChunked(3)) {
Parallel.ForEach(itemsChunk, item => Process(item));
//here you can insert a delay
}
This wastes not a single thread and is trivially simple. Parallel.ForEach used the current thread to process work items as well, so it does not sit idle. You can add your delay logic as well. Implementing AsChunked is left as an exercise for the reader... This function is supposed to split a list into chunks of the given size (3). The good thing about such a helper function is that it untangles the batching logic from the important parts.
Use
Task.Delay
instead
static async Task DoSomeProcess()
{
await Task.Delay(3000);
}
You are right, Thread.Sleep would block other tasks
Yes you can pair async/await pattern with Parallel.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With