Skip to content

Commit 553b10c

Browse files
committed
[修复]1. 修复Random线程安全的问题
#28
1 parent 7613e31 commit 553b10c

File tree

6 files changed

+598
-628
lines changed

6 files changed

+598
-628
lines changed

GameFrameX.Core/Timer/GlobalTimer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ private static DateTime NextSaveTime()
9090
var a = serverId % 1000;
9191
var b = a % GlobalConst.MAGIC;
9292
var c = GlobalSettings.SaveIntervalInMilliSeconds / GlobalConst.MAGIC;
93-
var r = ThreadLocalRandom.Current.Next(0, c);
93+
var r = GameFrameX.Utility.RandomHelper.Next(0, c);
9494
var delay = b * c + r;
9595
t = t.AddMilliseconds(delay);
9696

GameFrameX.Hotfix/Logic/Http/Player/ReqPlayerCreateHttpHandler.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,9 @@ private async Task<PlayerState> OnPlayerCreate(ReqPlayerCreate reqPlayerCreate)
4545
Id = ActorIdGenerator.GetActorId(GlobalConst.ActorTypePlayer),
4646
AccountId = reqPlayerCreate.Id,
4747
Name = reqPlayerCreate.Name,
48-
Level = (uint)Utility.Random.Next(1, 50),
48+
Level = (uint)Utility.RandomHelper.Next(1, 50),
4949
State = 0,
50-
Avatar = (uint)Utility.Random.Next(1, 50),
50+
Avatar = (uint)Utility.RandomHelper.Next(1, 50),
5151
};
5252
MetricsPlayerHelper.CreateCounterOptions.Inc();
5353
await GameDb.SaveOneAsync(playerState);
Lines changed: 155 additions & 157 deletions
Original file line numberDiff line numberDiff line change
@@ -1,158 +1,156 @@
1-
namespace GameFrameX.Utility.Extensions;
2-
3-
/// <summary>
4-
/// </summary>
5-
public static class CollectionExtensions
6-
{
7-
#region ICollectionExtensions
8-
9-
/// <summary>
10-
/// 检查集合是否为 null 或空。
11-
/// </summary>
12-
/// <typeparam name="T">集合元素的类型。</typeparam>
13-
/// <param name="self">要检查的集合。</param>
14-
/// <returns>如果集合为 null 或空,则为 true;否则为 false。</returns>
15-
public static bool IsNullOrEmpty<T>(this ICollection<T> self)
16-
{
17-
return self == null || self.Count <= 0;
18-
}
19-
20-
#endregion
21-
22-
/// <summary>
23-
/// 将一个可枚举集合的元素添加到哈希集合中。
24-
/// </summary>
25-
/// <typeparam name="T">哈希集合元素的类型。</typeparam>
26-
/// <param name="c">要添加元素的哈希集合。</param>
27-
/// <param name="e">要添加的元素的可枚举集合。</param>
28-
public static void AddRange<T>(this HashSet<T> c, IEnumerable<T> e)
29-
{
30-
foreach (var item in e)
31-
{
32-
c.Add(item);
33-
}
34-
}
35-
36-
#region DictionaryExtensions
37-
38-
/// <summary>
39-
/// 合并字典中的键值对。如果字典中已存在指定的键,则使用指定的函数对原有值和新值进行合并;否则直接添加键值对。
40-
/// </summary>
41-
/// <typeparam name="TKey">键的类型。</typeparam>
42-
/// <typeparam name="TValue">值的类型。</typeparam>
43-
/// <param name="self">要合并的字典。</param>
44-
/// <param name="k">要添加或合并的键。</param>
45-
/// <param name="v">要添加或合并的值。</param>
46-
/// <param name="func">用于合并值的函数。</param>
47-
public static void Merge<TKey, TValue>(this Dictionary<TKey, TValue> self, TKey k, TValue v, Func<TValue, TValue, TValue> func)
48-
{
49-
self[k] = self.TryGetValue(k, out var value) ? func(value, v) : v;
50-
}
51-
52-
/// <summary>
53-
/// 获取指定键的值,如果字典中不存在该键,则使用指定的函数获取值并添加到字典中。
54-
/// </summary>
55-
/// <typeparam name="TKey">键的类型。</typeparam>
56-
/// <typeparam name="TValue">值的类型。</typeparam>
57-
/// <param name="self">要操作的字典。</param>
58-
/// <param name="key">要获取值的键。</param>
59-
/// <param name="valueGetter">用于获取值的函数。</param>
60-
/// <returns>指定键的值。</returns>
61-
public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> self, TKey key, Func<TKey, TValue> valueGetter)
62-
{
63-
if (!self.TryGetValue(key, out var value))
64-
{
65-
value = valueGetter(key);
66-
self[key] = value;
67-
}
68-
69-
return value;
70-
}
71-
72-
/// <summary>
73-
/// 获取指定键的值,如果字典中不存在该键,则使用无参构造函数创建一个新的值并添加到字典中。
74-
/// </summary>
75-
/// <typeparam name="TKey">键的类型。</typeparam>
76-
/// <typeparam name="TValue">值的类型。</typeparam>
77-
/// <param name="self">要操作的字典。</param>
78-
/// <param name="key">要获取值的键。</param>
79-
/// <returns>指定键的值。</returns>
80-
public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> self, TKey key) where TValue : new()
81-
{
82-
return GetOrAdd(self, key, _ => new TValue());
83-
}
84-
85-
/// <summary>
86-
/// 根据指定条件从字典中移除键值对。
87-
/// </summary>
88-
/// <typeparam name="TKey">键的类型。</typeparam>
89-
/// <typeparam name="TValue">值的类型。</typeparam>
90-
/// <param name="self">要操作的字典。</param>
91-
/// <param name="predict">判断是否移除键值对的条件。</param>
92-
/// <returns>移除的键值对数量。</returns>
93-
public static int RemoveIf<TKey, TValue>(this Dictionary<TKey, TValue> self, Func<TKey, TValue, bool> predict)
94-
{
95-
var count = 0;
96-
foreach (var kv in self)
97-
{
98-
if (predict(kv.Key, kv.Value))
99-
{
100-
self.Remove(kv.Key);
101-
count++;
102-
}
103-
}
104-
105-
return count;
106-
}
107-
108-
#endregion
109-
110-
#region List<T>
111-
112-
/// <summary>
113-
/// 从列表中随机获取一个对象。
114-
/// </summary>
115-
/// <typeparam name="T">列表元素的类型。</typeparam>
116-
/// <param name="list">要随机的列表。</param>
117-
public static T Random<T>(this List<T> list)
118-
{
119-
var n = list.Count;
120-
var r = ThreadLocalRandom.Current;
121-
var index = r.Next(n);
122-
return list[index];
123-
}
124-
125-
/// <summary>
126-
/// 打乱列表中的元素顺序。
127-
/// </summary>
128-
/// <typeparam name="T">列表元素的类型。</typeparam>
129-
/// <param name="list">要打乱顺序的列表。</param>
130-
public static void Shuffer<T>(this List<T> list)
131-
{
132-
var n = list.Count;
133-
var r = ThreadLocalRandom.Current;
134-
for (var i = 0; i < n; i++)
135-
{
136-
var rand = r.Next(i, n);
137-
(list[i], list[rand]) = (list[rand], list[i]);
138-
}
139-
}
140-
141-
/// <summary>
142-
/// 从列表中移除满足条件的元素。
143-
/// </summary>
144-
/// <typeparam name="T">列表元素的类型。</typeparam>
145-
/// <param name="list">要操作的列表。</param>
146-
/// <param name="condition">用于判断元素是否满足移除条件的委托。</param>
147-
public static void RemoveIf<T>(this List<T> list, Predicate<T> condition)
148-
{
149-
var idx = list.FindIndex(condition);
150-
while (idx >= 0)
151-
{
152-
list.RemoveAt(idx);
153-
idx = list.FindIndex(condition);
154-
}
155-
}
156-
157-
#endregion
1+
namespace GameFrameX.Utility.Extensions;
2+
3+
/// <summary>
4+
/// </summary>
5+
public static class CollectionExtensions
6+
{
7+
#region ICollectionExtensions
8+
9+
/// <summary>
10+
/// 检查集合是否为 null 或空。
11+
/// </summary>
12+
/// <typeparam name="T">集合元素的类型。</typeparam>
13+
/// <param name="self">要检查的集合。</param>
14+
/// <returns>如果集合为 null 或空,则为 true;否则为 false。</returns>
15+
public static bool IsNullOrEmpty<T>(this ICollection<T> self)
16+
{
17+
return self == null || self.Count <= 0;
18+
}
19+
20+
#endregion
21+
22+
/// <summary>
23+
/// 将一个可枚举集合的元素添加到哈希集合中。
24+
/// </summary>
25+
/// <typeparam name="T">哈希集合元素的类型。</typeparam>
26+
/// <param name="c">要添加元素的哈希集合。</param>
27+
/// <param name="e">要添加的元素的可枚举集合。</param>
28+
public static void AddRange<T>(this HashSet<T> c, IEnumerable<T> e)
29+
{
30+
foreach (var item in e)
31+
{
32+
c.Add(item);
33+
}
34+
}
35+
36+
#region DictionaryExtensions
37+
38+
/// <summary>
39+
/// 合并字典中的键值对。如果字典中已存在指定的键,则使用指定的函数对原有值和新值进行合并;否则直接添加键值对。
40+
/// </summary>
41+
/// <typeparam name="TKey">键的类型。</typeparam>
42+
/// <typeparam name="TValue">值的类型。</typeparam>
43+
/// <param name="self">要合并的字典。</param>
44+
/// <param name="k">要添加或合并的键。</param>
45+
/// <param name="v">要添加或合并的值。</param>
46+
/// <param name="func">用于合并值的函数。</param>
47+
public static void Merge<TKey, TValue>(this Dictionary<TKey, TValue> self, TKey k, TValue v, Func<TValue, TValue, TValue> func)
48+
{
49+
self[k] = self.TryGetValue(k, out var value) ? func(value, v) : v;
50+
}
51+
52+
/// <summary>
53+
/// 获取指定键的值,如果字典中不存在该键,则使用指定的函数获取值并添加到字典中。
54+
/// </summary>
55+
/// <typeparam name="TKey">键的类型。</typeparam>
56+
/// <typeparam name="TValue">值的类型。</typeparam>
57+
/// <param name="self">要操作的字典。</param>
58+
/// <param name="key">要获取值的键。</param>
59+
/// <param name="valueGetter">用于获取值的函数。</param>
60+
/// <returns>指定键的值。</returns>
61+
public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> self, TKey key, Func<TKey, TValue> valueGetter)
62+
{
63+
if (!self.TryGetValue(key, out var value))
64+
{
65+
value = valueGetter(key);
66+
self[key] = value;
67+
}
68+
69+
return value;
70+
}
71+
72+
/// <summary>
73+
/// 获取指定键的值,如果字典中不存在该键,则使用无参构造函数创建一个新的值并添加到字典中。
74+
/// </summary>
75+
/// <typeparam name="TKey">键的类型。</typeparam>
76+
/// <typeparam name="TValue">值的类型。</typeparam>
77+
/// <param name="self">要操作的字典。</param>
78+
/// <param name="key">要获取值的键。</param>
79+
/// <returns>指定键的值。</returns>
80+
public static TValue GetOrAdd<TKey, TValue>(this Dictionary<TKey, TValue> self, TKey key) where TValue : new()
81+
{
82+
return GetOrAdd(self, key, _ => new TValue());
83+
}
84+
85+
/// <summary>
86+
/// 根据指定条件从字典中移除键值对。
87+
/// </summary>
88+
/// <typeparam name="TKey">键的类型。</typeparam>
89+
/// <typeparam name="TValue">值的类型。</typeparam>
90+
/// <param name="self">要操作的字典。</param>
91+
/// <param name="predict">判断是否移除键值对的条件。</param>
92+
/// <returns>移除的键值对数量。</returns>
93+
public static int RemoveIf<TKey, TValue>(this Dictionary<TKey, TValue> self, Func<TKey, TValue, bool> predict)
94+
{
95+
var count = 0;
96+
foreach (var kv in self)
97+
{
98+
if (predict(kv.Key, kv.Value))
99+
{
100+
self.Remove(kv.Key);
101+
count++;
102+
}
103+
}
104+
105+
return count;
106+
}
107+
108+
#endregion
109+
110+
#region List<T>
111+
112+
/// <summary>
113+
/// 从列表中随机获取一个对象。
114+
/// </summary>
115+
/// <typeparam name="T">列表元素的类型。</typeparam>
116+
/// <param name="list">要随机的列表。</param>
117+
public static T Random<T>(this List<T> list)
118+
{
119+
var n = list.Count;
120+
var index = Utility.RandomHelper.Next(n);
121+
return list[index];
122+
}
123+
124+
/// <summary>
125+
/// 打乱列表中的元素顺序。
126+
/// </summary>
127+
/// <typeparam name="T">列表元素的类型。</typeparam>
128+
/// <param name="list">要打乱顺序的列表。</param>
129+
public static void Shuffer<T>(this List<T> list)
130+
{
131+
var n = list.Count;
132+
for (var i = 0; i < n; i++)
133+
{
134+
var rand = Utility.RandomHelper.Next(i, n);
135+
(list[i], list[rand]) = (list[rand], list[i]);
136+
}
137+
}
138+
139+
/// <summary>
140+
/// 从列表中移除满足条件的元素。
141+
/// </summary>
142+
/// <typeparam name="T">列表元素的类型。</typeparam>
143+
/// <param name="list">要操作的列表。</param>
144+
/// <param name="condition">用于判断元素是否满足移除条件的委托。</param>
145+
public static void RemoveIf<T>(this List<T> list, Predicate<T> condition)
146+
{
147+
var idx = list.FindIndex(condition);
148+
while (idx >= 0)
149+
{
150+
list.RemoveAt(idx);
151+
idx = list.FindIndex(condition);
152+
}
153+
}
154+
155+
#endregion
158156
}

GameFrameX.Utility/Extensions/ThreadLocalRandom.cs

Lines changed: 0 additions & 19 deletions
This file was deleted.

GameFrameX.Utility/GameFrameX.Utility.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
<ItemGroup>
4545
<PackageReference Include="GameFrameX.Foundation.Hash" Version="1.3.2" />
4646
<PackageReference Include="GameFrameX.Foundation.Logger" Version="1.3.2" />
47+
<PackageReference Include="Tedd.RandomUtils" Version="1.0.6" />
4748
<PackageReference Include="Yitter.IdGenerator" Version="1.0.14" />
4849
<PackageReference Include="Mapster" Version="7.4.0" />
4950
</ItemGroup>

0 commit comments

Comments
 (0)