【发布时间】:2018-04-19 08:20:57
【问题描述】:
我正在尝试更新存储在可靠字典中的数据项,如下所示:
private async Task UpdateDictionary(IEnumerable<long> keys)
{
var dataDictionary = await this.stateManager.GetOrAddAsync<IReliableDictionary2<long, DataItem>>("DataItemsDictionary");
using (var tx = this.stateManager.CreateTransaction())
{
// When I replace parallel with foreach, it works fine.
keys.AsParallel().ForAll(async k =>
{
// Below line is line 54 in the exception
var dataItem = await dataDictionary.TryGetValueAsync(tx, k);
if (dataItem.HasValue)
{
ServiceEventSource.Current.Message(dataItem.Value.ToString());
var newItem = new DataItem(dataItem.Value);
newItem.TransmissionState = TransmissionState.InReview;
await dataDictionary.SetAsync(tx, newItem.Id, newItem);
}
});
await tx.CommitAsync();
}
}
System.ArgumentException occurred
HResult=0x80070057
Message=The key already existed in the dictionary.
Source=mscorlib
StackTrace:
at System.Collections.Concurrent.ConcurrentDictionary`2.System.Collections.Generic.IDictionary<TKey,TValue>.Add(TKey key, TValue value)
at System.Fabric.Store.TStore`5.CreateStoreReadWriteTransaction(Transaction replicatorTransaction)
at System.Fabric.Store.TStore`5.CreateOrFindTransaction(Transaction replicatorTransaction)
at Microsoft.ServiceFabric.Data.Collections.DistributedDictionary`2.<TryGetValueAsync>d__117.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at StateService.StateManager.DataItemTask.<>c__DisplayClass2_1.<<UpdateDictionary>b__0>d.MoveNext() in D:\SFApplication\StateManager\Tasks\DataItemTask.cs:line 54
我不明白为什么 TryGetValueAsync 函数试图添加到字典中。理想情况下,它应该只获取元素。
奇怪的是,当我删除并行查询并将其替换为 foreach 时,它工作正常。在事务中使用并行不安全吗?
【问题讨论】: