I'm batching up items and processing them in parallel similarly to what is shown below. I need information not returned in the task that is sent through the two eventhandlers shown below (status updates). Can these be handled in a parallel foreach loop? I'm assuming that results would be stepping on each other setup the way it is currently? How to safely update the status in a SQL database table?
public function async task<junk> blahblahblah(List<items> unprocessedItems)
{
var tasks = new List<Task>();
Parallel.ForEach(unprocessedItems, item =>
{
var exporter = new Exporter();
exporter.ExportEnded += Exporter_ExportEnded;
exporter.StatisticsReceived += Exporter_StatisticsReceived;
var exporterTask = exporter.ExportAsync(cameraConfig, PlaybackMode.Sequential, fileName, true);
//do exporter task stuff
tasks.Add(exporterTask);
}
await Task.WhenAll(tasks);
}
private void Exporter_StatisticsReceived(object sender, StatisticsEventArgs e)
{
//do stuff with event information
//update percent status in DB for each parallel row independently.
}
private void Exporter_ExportEnded(object sender, EndedEventArgs e)
{
//do stuff with event information
//log results in database.
}
I'm batching up items and processing them in parallel similarly to what is shown below.
The usage of Parallel.ForEach
is incorrect. It calls List<T>.Add
from multiple threads, and Add
is not a threadsafe method. More broadly, it parallelizes object construction, adding a couple event handlers, starting the export (not the export itself), and adding an item to a list. The total amount of work being parallelized is practically nothing.
It would be more idiomatic to start all the exports one at a time, and then asynchronously wait for them all to complete:
var tasks = unprocessedItems.Select(item =>
{
var exporter = new Exporter();
exporter.ExportEnded += Exporter_ExportEnded;
exporter.StatisticsReceived += Exporter_StatisticsReceived;
return exporter.ExportAsync(cameraConfig, PlaybackMode.Sequential, fileName, true);
}).ToList();
await Task.WhenAll(tasks);
I need information not returned in the task that is sent through the two eventhandlers shown below (status updates). Can these be handled in a parallel foreach loop?
I don't think that makes sense. The event handlers will already be coming in on thread pool threads, with multiple happening concurrently.
How to safely update the status in a SQL database table?
The same way any other SQL update is done? SQL databases are comfortable with concurrency.
You will need to handle race conditions, such as StatisticsReceived
invoked after ExportEnded
. A properly-designed SQL statement should be able to handle that.