I have a background service which in C# which ingest 3600 xml files (5Gb file size in total) to SQL Server database. The duration to complete the ingestion is around 16 hours. I use hangfire to create 3 jobs/threads and each job will have one folder to ingest, Folder A, B, C.
Problem is Folder C is very extra heavy. My idea is split the files in Folder C into two folders, folder C1 and folder C2. So now, I have 4 jobs/threads, Folder A, B, C1 and C2. But the problem is C1 and C2 job hit database error below which I believe due to they both assessing to the same table.
An exception occurred in the database while saving changes for context type 'xxxContext'. System.InvalidOperationException: A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext
and another time with this error:
An exception occurred in the database while saving changes for context type 'xxxContext'. System.InvalidOperationException: Collection was modified; enumeration operation may not execute.
and error from hangfire is below:
Hangfire.Storage.DistributedLockTimeoutException Timeout expired. The timeout elapsed prior to obtaining a distributed lock on the 'HangFire:IIngestService.IngestPersonXML' resource.
Hangfire.Storage.DistributedLockTimeoutException: Timeout expired. The timeout elapsed prior to obtaining a distributed lock on the 'HangFire:IIngestService.IngestPersonXML' resource.
When I use Parallel.ForEach
, I also get this error:
System.InvalidOperationException: 'Operations that change non-concurrent collections must have exclusive access. A concurrent update was performed on this collection and corrupted its state. The collection's state is no longer correct.'
I only need to insert into db. No update or delete operation needed. Is there any workaround for this?