La nuova transazione Entity Framework non è consentita in quanto vi sono altri thread in esecuzione nella sessione, salvataggio multi-thread

Sto cercando di salvare su un DB il log di un processo multi-thread ma sto ricevendo il seguente errore: la nuova transazione non è consentita perché ci sono altri thread in esecuzione nella sessione.

in ogni battistrada ho questa funzione:

internal bool WriteTrace(IResult result, string message, byte type) { SPC_SENDING_TRACE trace = new SPC_SENDING_TRACE( message, Parent.currentLine.CD_LINE, type, Parent.currentUser.FULLNAME, Parent.guid); Context.SPC_SENDING_TRACE.AddObject(trace); if (Context.SaveChanges(result) == false) return false; return true; } 

il contesto è diverso per ogni thread, ma la connessione con il DB è sempre la stessa.

c’è un modo per risolvere questo problema?

grazie Andrea

    Dovresti creare un contesto per ogni transazione e poi eliminarlo, puoi farlo in questo modo:

     using(var ctx = new MyContext()) { //do transaction here } 

    Dopo la parentesi chiusa, il contesto viene eliminato.

    Per una migliore comprensione, fai riferimento a questo post in cui puoi trovare un’ottima risposta di ken2k . Spero che tu possa risolvere il tuo problema 🙂

    AGGIORNARE:

    Dovresti anche provare ad aggiungere .ToList() ad ogni query LINQ che hai. Quando si itera su un risultato LINQ, non è ansible apportare modifiche finché l’iterazione non è terminata. Verifica se hai qualcosa del genere o condividi altro codice, ad esempio il codice in cui si chiama WriteTrace . Spero che questa volta ti aiuti davvero.

    Utilizzo il framework di entity framework in un ambiente a più thread, in cui thread, ui e background (sia STA che MTA) possono aggiornare contemporaneamente lo stesso database. Ho risolto questo problema ricreando la connessione dell’ quadro da zero all’inizio dell’utilizzo su qualsiasi nuovo thread in background. Esaminando l’istanza di connessione dell’entity framework ConnectionString mostra un lettore guida che presumo sia utilizzato per colbind istanze di connessione comuni. Ricreando la connessione dell’ quadro da zero i valori guid sono diversi per ogni thread e non sembra che si verifichi alcun conflitto.

     // Build the connection string. var sqlBuilder = new SqlConnectionStringBuilder(); sqlBuilder.DataSource = serverName; sqlBuilder.InitialCatalog = databaseName; sqlBuilder.MultipleActiveResultSets = true; ... var providerString = sqlBuilder.ToString(); var sqlConnection = new SqlConnection(providerString); // Build the emtity connection. Assembly metadataAssembly = Assembly.GetExecutingAssembly(); Assembly[] metadataAssemblies = { metadataAssembly }; var metadataBase = @"res://*/{0}.csdl|res://*/{0}.ssdl|res://*/{0}.msl"; var dbModelMetadata = String.Format(metadataBase, objectContextTypeModelName); // eg: "res://*/Models.MyDatabaseModel.csdl|res://*/Models.MyDatabaseModel.ssdl|res://*/Models.MyDatabaseModel.msl" var modelMetadataPaths = modelMetadata.Split('|'); var metadataWorkspace = new MetadataWorkspace(modelMetadataPaths, metadataAssemblies); var entityDbConnection = new EntityConnection(metadataWorkspace, sqlConnection); return entityDbConnection;