C#并发字典未在Azure函数中添加或更新值

C#并发字典未在Azure函数中添加或更新值,c#,azure-functions,concurrentdictionary,C#,Azure Functions,Concurrentdictionary,我正试图将一些键值对缓存到并发字典中,以避免每次需要值时都去cosmos。这是我的密码 public class ActivityLogHubIngress { private readonly ICustomerDbService _customerDbService; private static ConcurrentDictionary<string, string> _customerIdLookup => ne

我正试图将一些键值对缓存到并发字典中,以避免每次需要值时都去cosmos。这是我的密码

public class ActivityLogHubIngress
    {
        private readonly ICustomerDbService _customerDbService;
        
        private static ConcurrentDictionary<string, string> _customerIdLookup => new ConcurrentDictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);

        public ActivityLogHubIngress(ICustomerDbService customerDbService)
        {
            _customerDbService = customerDbService;
        }

        [FunctionName("ActivityLogHubIngress")]
        public async Task Run([EventHubTrigger("activity-log-events", Connection = "ActivityLogEventHub")] EventData[] events, ILogger log)
        {
         //Some code removed for brevity. At some point in this Azure Function the following line gets called to retrieve a customer ID.
         
         string customerId = await GetCustomerId(activityLogHubEvent.SubscriptionId, log); 

         //Some code removed for brevity. 
        }

private async Task<string> GetCustomerId(string subscriptionId, ILogger log = null)
        {
            if (_customerIdLookup.TryGetValue(subscriptionId, out string customerId))
            {
                return customerId;
            }

            var customer = await _customerDbService.GetCustomerBySubscription(subscriptionId);
            if(customer is null)
            {
                _customerIdLookup.AddOrUpdate(subscriptionId, string.Empty, (key, value) => string.Empty);

                if (log != null)
                {
                    log.LogInformation(ApplicationEvents.ActivityLogUnknownSubscriptionFailure,
                    $"Added Non-Customer ({subscriptionId}: null) to _customerIdLookup" +
                    $"\nListing _customerIdLookup dictionary (item count {_customerIdLookup.Count})" +
                    $"\n{string.Join("\n", _customerIdLookup.Keys.Select(k => $"{k}: {_customerIdLookup[k]}").ToList())}");
                }

                return null;
            }

            _customerIdLookup.AddOrUpdate(subscriptionId, customer.Id, (key, value) => customer.Id);

            if(log != null)
            {
                log.LogInformation(ApplicationEvents.ActivityLogUnknownSubscriptionFailure,
                $"Added ({subscriptionId}: {customer.Id}) to _customerIdLookup" +
                $"\nListing _customerIdLookup dictionary (item count {_customerIdLookup.Count})" +
                $"\n{string.Join("\n", _customerIdLookup.Keys.Select(k => $"{k}: {_customerIdLookup[k]}").ToList())}");
            }                

            return customer.Id;
        }
其中项目计数始终为零


我做了什么错误的事情而没有编写词典?

问题在于您对词典的声明:

private static ConcurrentDictionary<string, string> _customerIdLookup => new ConcurrentDictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
私有静态ConcurrentDictionary\u customerIdLookup=>新的ConcurrentDictionary(StringComparer.InvariantCultureInogoreCase);

请注意lambda符号
=>
,这意味着每次访问成员时都会返回一个新实例。

问题在于您对字典的声明:

private static ConcurrentDictionary<string, string> _customerIdLookup => new ConcurrentDictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
私有静态ConcurrentDictionary\u customerIdLookup=>新的ConcurrentDictionary(StringComparer.InvariantCultureInogoreCase);

请注意lambda符号
=>
,这意味着您每次访问成员时都会返回一个新实例。

您是在无服务器(消费)计划中托管,还是在专用的应用程序服务计划中托管?你能保证你的功能每次都在同一台服务器上,在同一个过程中运行吗?这是一个消费计划,但我可以在app insights中看到服务器实例加速,我希望一些流量能够共享同一个静态成员。而且看起来很奇怪,即使每个请求都通过不同的服务器,在添加之后编写的日志在字典中显示0项。是的,我现在只是在阅读代码,我没有意识到你在同一个方法调用中立即记录了计数。另外,我认为注入的
ILogger
永远不会为空。如果日志记录被禁用,记录器仍将被注入,但不会输出到任何东西这里有一个演示相同行为的最小示例:您是在无服务器(消费)计划上托管,还是在专用应用程序服务计划上托管?你能保证你的功能每次都在同一台服务器上,在同一个过程中运行吗?这是一个消费计划,但我可以在app insights中看到服务器实例加速,我希望一些流量能够共享同一个静态成员。而且看起来很奇怪,即使每个请求都通过不同的服务器,在添加之后编写的日志在字典中显示0项。是的,我现在只是在阅读代码,我没有意识到你在同一个方法调用中立即记录了计数。另外,我认为注入的
ILogger
永远不会为空。如果日志记录被禁用,记录器仍将被注入,但它不会输出到任何东西这里有一个演示相同行为的最小示例:Awesome catch!我怎么没看到呢?我只是把它移到一个静态构造函数。这应该可以解决问题。谢谢你成为第二双眼睛。您不需要静态构造函数,只需将其从
=>
更改为
=
即可!我怎么没看到呢?我只是把它移到一个静态构造函数。这应该可以解决问题。谢谢你成为第二双眼睛。您不需要静态构造函数,只需将其从
=>
更改为
=