【问题标题】:IReliableDictionary TryGetValueAsync() throws exception "The key already existed in the dictionary"IReliableDictionary TryGetValueAsync() 抛出异常“字典中已存在密钥”
【发布时间】: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 时,它工作正常。在事务中使用并行不安全吗?

【问题讨论】:

    标签: azure-service-fabric


    【解决方案1】:

    事务不能处理对同一事务的并行请求。这在IReliableDictionary2 的文档页面上有所描述:

    事务是并发的单位。用户可以拥有多个 在任何给定时间点进行中的交易,但对于给定的 每个 API 必须一次调用一个。 调用任何采用 Microsoft.ServiceFabric.Data.ITransaction 的异步 Reliable Collection 方法时,您必须 在调用之前等待返回的任务完成 使用相同事务的另一种方法。

    Parallel 不起作用,而 foreach 确实起作用,因为您必须等待返回的 Task 完成,然后才能使用同一事务调用另一个方法。

    【讨论】:

      猜你喜欢
      • 2021-10-11
      • 1970-01-01
      • 2017-11-03
      • 1970-01-01
      • 2017-08-21
      • 1970-01-01
      • 2014-02-10
      • 2016-02-17
      • 2015-01-28
      相关资源
      最近更新 更多