Non è possibile sottolineare a sufficienza quanto sia semplice effettuare l'errore descritto in alto.I cannot stress enough how easy it is to make the kind of mistake shown above.Sarà possibile apprendere l'errore solo se/quando il processo si interrompe.And, you will only learn about the mistake if/when the process goes down.Il modo corretto per scrivere il codice è semplicemente invertire le due righe:The correct way to write the code is simply to reverse the two lines:

using (ITransaction tx = StateManager.CreateTransaction()) {
// Use the user’s name to look up their data
ConditionalValue<User> user =
await m_dic.TryGetValueAsync(tx, name);
// The user exists in the dictionary, update one of their properties.
if (user.HasValue) {
// The line below updates the property’s value in memory only; the
// new value is NOT serialized, logged, & sent to secondary replicas.
user.Value.LastLogin = DateTime.UtcNow; // Corruption!
await tx.CommitAsync();
}
}

Il modo corretto per aggiornare un valore in una raccolta Reliable Collections è fare riferimento al valore esistente e tenere in considerazione l'oggetto a cui fa riferimento tramite il riferimento non modificabile.The correct way to update a value in a reliable collection, is to get a reference to the existing value and consider the object referred to by this reference immutable.Quindi, creare un nuovo oggetto come copia esatta dell'oggetto originale.Then, create a new object which is an exact copy of the original object.A questo punto, è possibile modificare lo stato di questo nuovo oggetto e scrivere il nuovo oggetto nella raccolta in modo che venga serializzato in array di byte, aggiunto al file locale e inviato alle repliche.Now, you can modify the state of this new object and write the new object into the collection so that it gets serialized to byte arrays, appended to the local file and sent to the replicas.Dopo aver eseguito il commit delle modifiche, gli oggetti interni alla memoria, il file locale e tutte le repliche hanno lo stesso stato.After committing the change(s), the in-memory objects, the local file, and all the replicas have the same exact state.Tutto è in posizione.All is good!

using (ITransaction tx = StateManager.CreateTransaction()) {
// Use the user’s name to look up their data
ConditionalValue<User> currentUser =
await m_dic.TryGetValueAsync(tx, name);
// The user exists in the dictionary, update one of their properties.
if (currentUser.HasValue) {
// Create new user object with the same state as the current user object.
// NOTE: This must be a deep copy; not a shallow copy. Specifically, only
// immutable state can be shared by currentUser & updatedUser object graphs.
User updatedUser = new User(currentUser);
// In the new object, modify any properties you desire
updatedUser.LastLogin = DateTime.UtcNow;
// Update the key’s value to the updateUser info
await m_dic.SetValue(tx, name, updatedUser);
await tx.CommitAsync();
}
}

[DataContract]
// If you don’t seal, you must ensure that any derived classes are also immutable
public sealed class UserInfo {
private static readonly IEnumerable<ItemId> NoBids = ImmutableList<ItemId>.Empty;
public UserInfo(String email, IEnumerable<ItemId> itemsBidding = null) {
Email = email;
ItemsBidding = (itemsBidding == null) ? NoBids : itemsBidding.ToImmutableList();
}
[OnDeserialized]
private void OnDeserialized(StreamingContext context) {
// Convert the deserialized collection to an immutable collection
ItemsBidding = ItemsBidding.ToImmutableList();
}
[DataMember]
public readonly String Email;
// Ideally, this would be a readonly field but it can't be because OnDeserialized
// has to set it. So instead, the getter is public and the setter is private.
[DataMember]
public IEnumerable<ItemId> ItemsBidding { get; private set; }
// Since each UserInfo object is immutable, we add a new ItemId to the ItemsBidding
// collection by creating a new immutable UserInfo object with the added ItemId.
public UserInfo AddItemBidding(ItemId itemId) {
return new UserInfo(Email, ((ImmutableList<ItemId>)ItemsBidding).Add(itemId));
}
}