Après de nombreux tests, j'ai finalement découvert que le problème n'était pas du tout dans Entity Framework ou NpgSql, mais le retard que je voyais était causé par la mise en cache en écriture. J'écrivais toujours un fichier de 30 Mo avant d'insérer une ligne dans le tableau 1 et je pensais que l'écriture du fichier avait été effectuée après le retour de File.WriteAllBytes, de sorte que cela n'aurait aucune incidence sur les futures instructions de synchronisation. Cependant, au niveau de la couche du système d'exploitation, l'écriture sur le disque n'était pas vraiment terminée au moment où l'instruction d'insertion a été exécutée, ce qui a retardé artificiellement l'instruction d'insertion.
Je l'ai prouvé avec le code suivant :
Stopwatch sw1 = new Stopwatch();
sw1.Start();
File.WriteAllBytes(myBytes);
sw1.Stop();
Thread.Sleep(1000);
Stopwatch sw2 = new Stopwatch();
sw2.Start();
MethodThatInsertsIntoTable1();
sw2.Stop();
le chronomètre 1 a montré que File.WriteAllBytes prenait toujours environ 500 ms, puis le chronomètre 2 a chronométré environ 20 à 30 secondes.
Si je change MethodThatInsertsIntoTable1 pour insérer dans une autre table, cela prend encore 20 à 30 secondes, quelle que soit la table.
Si j'augmente Thread.Sleep(1000) à Thread.Sleep(30000) alors le chronomètre 2 enregistre que l'insertion prend moins de 10 millisecondes.
Cela montre que même après que File.WriteAllBytes a rendu le contrôle au programme, l'écriture du fichier sur le disque n'est pas réellement terminée.
L'environnement sur lequel je fonctionnais était Linux sur un raspberry pi. Un test de vitesse d'écriture confirme que ma vitesse d'écriture sur la carte SD est légèrement supérieure à 1 Mo/s, ce qui correspondrait aux résultats que je vois, 20 à 30 secondes pour écrire un fichier de 30 Mo, cela ne pourrait pas être fait dans les 500 ms ce chronomètre 1 dit que oui.
Un autre utilisateur semble rencontrer un problème à cause de cela dans File.WriteAllBytes ne ne pas bloquer
Après avoir ajouté un disque dur USB SSD externe au raspberry pi et changé pour y enregistrer le fichier à la place, l'enregistrement du fichier ne prend que 0,5 seconde et le problème disparaît.