Bonjour,

je met en place un système de création de zone en fonction de l'emplacement de l'utilisateur, il se peut que 2 utilisateurs sur la même zone se connecte en même temps, pour éviter de créer 2 fois la même zone j'avais mis au départ un lock, chose plus possible en async (je sais qu'il y a les semaphore).
J'aimerai optimiser la création de ces zones, il y a des millions voir des milliards de possibilités donc je ne peux pas toutes les créer, celle-ci sont défini par leur coordonnées, est-ce qu'il y aurait moyen de bloquer la création en fonction des coordonnées, peut être faut-il utiliser un système de queue.

J'attends vos suggestions merci.

Le code actuel :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
 
    public HashSet<AreaEntity> Areas
        {
            get
            {
                if (!cache.TryGetValue("Areas", out areas))
                {
                    areas = new HashSet<AreaEntity>();
                }
 
                return areas;
 
            }
            set
            {
                var cacheEntry = cache.Set("Areas", value, TimeSpan.FromMinutes(15));
                areas = cacheEntry;
            }
        }
 
 
public async Task<HashSet<AreaEntity>> GetAreasForPlayer(int playerId, decimal latitude, decimal longitude)
        {
            // todo lock alternative
            //lock (areaLock)
            //{
 
            HashSet<AreaEntity> areasPlayers = new HashSet<AreaEntity>();
 
            removePlayerFromArea(playerId);
            var area = await GetAreaOrCreate(latitude, longitude);
            area.PlayerIds.Add(playerId);
            area.LastCall = DateTime.UtcNow.Ticks;
            areasPlayers.Add(area);
            decimal lat1 = (latitude - area.LatitudeMin) * 1000;
            decimal long1 = (longitude - area.LongitudeMin) * 1000;
            // we get 3 near area
            AreaEntity area1 = null;
            AreaEntity area2 = null;
            AreaEntity area3 = null;
            if (lat1 < 5)
            {
                area1 = await GetAreaOrCreate(area.LatitudeMin - 0.01m, area.LongitudeMin);
                if (long1 < 10)
                {
                    area2 = await GetAreaOrCreate(area.LatitudeMin - 0.01m, area.LongitudeMin - 0.02m);
                    area3 = await GetAreaOrCreate(area.LatitudeMin, area.LongitudeMin - 0.02m);
                }
                else
                {
                    area2 = await GetAreaOrCreate(area.LatitudeMin - 0.01m, area.LongitudeMin + 0.02m);
                    area3 = await GetAreaOrCreate(area.LatitudeMin, area.LongitudeMin + 0.02m);
                }
            }
            else
            {
                area1 = await GetAreaOrCreate(area.LatitudeMin + 0.01m, area.LongitudeMin);
                if (long1 < 10)
                {
                    area2 = await GetAreaOrCreate(area.LatitudeMin + 0.01m, area.LongitudeMin - 0.02m);
                    area3 = await GetAreaOrCreate(area.LatitudeMin, area.LongitudeMin - 0.02m);
                }
                else
                {
                    area2 = await GetAreaOrCreate(area.LatitudeMin + 0.01m, area.LongitudeMin + 0.02m);
                    area3 = await GetAreaOrCreate(area.LatitudeMin, area.LongitudeMin + 0.02m);
                }
            }
            areasPlayers.Add(area1);
            areasPlayers.Add(area2);
            areasPlayers.Add(area3);
 
            Areas = areasPlayers;
 
            return areasPlayers;
            // }
        }
 
  private async Task<AreaEntity> GetAreaOrCreate(decimal latitude, decimal longitude)
        {
            AreaEntity area;
            if (Areas != null)
            {
                area = Areas.SingleOrDefault(a => a.CheckCoord(latitude, longitude));
                if (area != null)
                {
                    return area;
                }
            }
            area = await CreateArea(latitude, longitude);
            Areas.Add(area);
 
            return area;
        }
 
   public async Task<AreaEntity> CreateArea(decimal latitude, decimal longitude)
        {
            var area = new AreaEntity();
            // for lat we have area every 0.01              
            decimal lat = Math.Truncate(100 * latitude) / 100;
            // for long we have area every 0.02     
            decimal longi = Math.Truncate(100 * longitude) / 100;
            if ((longi * 100) % 2 != 0)
            {
                longi -= 0.01m;
            }
            area.LatitudeMin = lat;
            area.LongitudeMin = longi;
            area.LatitudeMax = lat + 0.01m;
            area.LongitudeMax = longi + 0.02m;
            area.MonsterEntities = new HashSet<MonsterEntity>();
            area.PlayerIds = new HashSet<int>();
 
            Random rand = new Random();
            int length = rand.Next(30, 40);
            for (int i = 0; i < length; i++)
            {
                var monster = await monsterService.CreateMonster(i, area.LatitudeMin, area.LatitudeMax, area.LongitudeMin, area.LongitudeMax);
 
                area.MonsterEntities.Add(monster);
            };
            // todo delete
            var t = await monsterService.CreateMonster(1, latitude, latitude, longitude, longitude);
            area.MonsterEntities.Add(t);
 
            return area;
        }