在无法从另一个并发调用/线程访问的类之间共享字典

问题描述 投票:0回答:1

我们正在开发 Azure Function App。我们正在使用依赖注入。我们将一些数据存储在类的“public static IDictionary”中。稍后我们需要从另一个类使用相同的 IDictionary。并发调用正在修改字典,这会导致数据无声丢失。我们需要在三个类之间共享一个字典,该字典无法从另一个并发调用/线程访问。怎样才能正确实施呢?

我们通过以下方式实现了这两个类

using System;
using System.Collections.Generic;

namespace ConsoleApp
{
    class Class1
    {
        public static IDictionary<string, List<String>> details;
        public Class1()
        {
            Class1.details = new Dictionary<string, List<string>>();
        }

        public void Method1()
        {
            Class1.details.Add("1", new List<string>() { "A1", "A2" });
        }
        public void Method2()
        {
            Class1.details.Add("2", new List<string>() { "B1", "B2" });
        }
    }

    class Class2
    {
        private readonly Class1 class1;
        public Class2(Class1 class1)
        {
            this.class1 = class1;
        }
        public void MethodXYZ()
        {
            Console.WriteLine(String.Join(";", Class1.details["1"]));
            Console.WriteLine(String.Join(";", Class1.details["2"]));
        }
    }

    class MyHttpTrigger
    {
        private readonly Class1 class1;
        private readonly Class2 class2;
        public MyHttpTrigger(Class1 class1, Class2 class2)
        {
            this.class1 = class1;
            this.class2 = class2;
        }

        [FunctionName("MyHttpTrigger")]
        public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)] HttpRequest req)
        {
            this.class1.Method1();
            this.class1.Method2();
            //a lot of process
            this.class2.MethodXYZ();
        }
    }
}

当一个调用运行较长时间时,另一个并发调用正在创建一个新的字典。所以我们在执行过程中会丢失数据。如何才能正确落实这个要求呢?

c# asp.net-core concurrency static azure-functions
1个回答
0
投票

我建议您阅读这篇文章以了解无状态与有状态执行之间的区别。有趣的部分在这里:

Azure Functions 被设想为一种服务,主要任务是以无状态方式大规模处理快速爆发的事件。 Azure Functions 最常见的一个用例涉及大规模执行快速突发的无状态自定义代码。这些场景的特点是持续时间短(不超过五分钟),并且代码在请求之间不持有任何状态或锁。

然后

Azure Functions 可以使用提供真正无服务器特性的消费层进行托管,也可以通过使用专用容量选项的应用服务计划进行托管。在后一种情况下,消费层中的一些限制(例如每个请求五分钟超时)将不适用。

这意味着根据您选择的托管计划,您有两种选择。但您始终可以使用无状态函数,并使用 Redis Cache(或任何 DB - NoSql、SQL)之类的东西来存储/共享执行之间的状态(您的数据)。

© www.soinside.com 2019 - 2024. All rights reserved.