2013-03-12 7 views
9

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

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 filo, ma la connessione con il DB è sempre lo stesso.

c'è un modo per risolvere questo problema?

si Andrea

risposta

34

ringraziamento È necessario creare un contesto per ogni transazione e quindi disporre di esso, si può fare in questo modo:

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

dopo la parentesi chiusa contesto è disposto.

Per una migliore comprensione, fare riferimento a this post dove è possibile trovare un'ottima risposta entro ken2k. Spero che tu possa risolvere si emette :)

UPDATE:

Si dovrebbe anche provare ad aggiungere .ToList() ad ogni query LINQ che avete. Quando si itera su un risultato LINQ, non è possibile apportare modifiche finché l'iterazione non è terminata. Controlla se hai qualcosa del genere o condividi altro codice, ad esempio il pezzo di codice in cui chiami il numero WriteTrace. Spero che questa volta ti aiuti davvero.

+0

ancora lo stesso errore, ho un altro contesto per l'applicazione principale (non multithread) ma non sta scrivendo quando il multithread è in esecuzione. può ancora causare alcuni problemi? – andrea

+0

@andrea non ha un altro contesto per la tua app principale, prova a creare un contesto solo quando hai bisogno di richiedere, aggiungere, eliminare o aggiornare qualcosa dal tuo db, fallo con 'using' come ti ho detto nella mia risposta per ogni ** singola ** transazione e se ciò non risolve, aggiungi un 'lock' a' context.SaveChanges() '. Spero che questo aiuti, anche se non ne sono sicuro, così, buona fortuna !!! Rispondi comunque, per favore;) – ecampver

+0

@andrea dimentica il mio ultimo commento, prova prima il mio aggiornamento della risposta. – ecampver

0

Uso il framework di entità 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'entità da zero all'inizio dell'utilizzo su qualsiasi nuovo thread in background. Esaminando l'istanza di connessione dell'entità ConnectionString mostra un lettore guida che presumo sia utilizzato per collegare istanze di connessione comuni. Ricreando la connessione dell'entità 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; 
+0

Si prega di non copiare e incollare la maggior parte della risposta a domande diverse. – Andy

Problemi correlati