Tengo un método que inserta en una tabla una identificación, un conjunto de UDT y una fecha.
public class MessageQueueNext { public string Id { get; set; } public List<UDTMessage> Messages { get; set; } public DateTimeOffset Updated { get; set; } } private static Lazy<PreparedStatement> InsertStatement = new Lazy<PreparedStatement>( () => { return CassandraDB.Instance.Session.Prepare ( @"INSERT INTO SomeTable (id, messages, updated) VALUES (?, ?, ?)" ); }); public async Task InsertAsync(SomeObj obj) { var statement = BindValues( InsertStatement.Value, new dynamic[] { obj.Id, obj.Messages, obj.Updated } ); await CassandraDB.Instance.Session.ExecuteAsync(statement); } private BoundStatement BindValues(PreparedStatement ps, dynamic[] values) { var statement = ps.Bind ( values[0] ?? Unset.Value, values[1] ?? new List<UDTMessage>(), values[2] ?? Unset.Value ); return statement; }En algún momento, este método lanza una excepción.
Se modificó la colección; Es posible que la operación de enumeración no se ejecute. en System.Collections.Generic.List`1.Enumerator.MoveNextRare() en Cassandra.Serialization.CollectionSerializer.Serialize(UInt16 protocolVersion, IEnumerable value) en Cassandra.Serialization.GenericSerializer.Serialize(ProtocolVersion version, Object value) en Cassandra.QueryProtocolOptions .Write(FrameWriter wb, Boolean isPrepared) en Cassandra.Requests.BaseRequest.WriteFrame(Int16 streamId, MemoryStream stream, ISerializer connectionSerializer) en Cassandra.OperationState.WriteFrame(Int16 streamId, MemoryStream memoryStream, ISerializer serializer, Int64 timestamp) en Cassandra.Connections .Connection.RunWriteQueueAction() --- Fin del seguimiento de la pila desde la ubicación anterior donde se lanzó la excepción ---
¿Alguien puede ayudarme con lo que podría causar eso? Según entiendo, obj.Messages se cambia en algún lugar del camino. ¿O es posible que haya cambiado en una función que llama a InsertAsync (...), pero justo después de llamar a InsertAsync (...) cambia el valor de obj.Messages?
Método que llama a InsertAsync(...)
public async Task PersistMessageQueue(UDTMessage msg) { var DAO = new DAO(); var list = await _cache.GetMessages(msg.Id); if (list == null) { list = new List<UDTMessage>(); } list.Add(msg); var someObj = new SomeObj(); someObj.ToId = msg.Id; someObj.Messages = list; someObj.Updated = DateTimeOffset.UtcNow; await DAO.InsertAsync(messageQueueNext); _cache.AddElement(msg); }Mirando el método principal (de su comentario):
public async Task PersistMessageQueue(UDTMessage msg) { var DAO = new DAO(); var list = await _cache.GetMessages(msg.Id); if (list == null) { list = new List<UDTMessage>(); } list.Add(msg); var someObj = new SomeObj(); someObj.ToId = msg.Id; someObj.Messages = list; someObj.Updated = DateTimeOffset.UtcNow; await DAO.InsertAsync(messageQueueNext); _cache.AddElement(msg); } Parece que está almacenando el objeto List en un caché, pasándoselo al controlador, pero cada llamada a PersistMessageQueue() modificará este objeto List , por lo que podría encontrarse con el problema de que el controlador itera a través del objeto List mientras otra llamada a PersistMessageQueue() está modificando ese mismo objeto List .
La solución es clonar el objeto List antes de llamar a Session.ExecuteAsync() si esto es lo que está causando el problema.