11using Microsoft . Win32 ;
2- using System ;
3- using System . Collections . Generic ;
4- using System . Linq ;
2+ using System . Collections . Concurrent ;
3+ using System . Reflection ;
54
65namespace BASpark
76{
@@ -96,6 +95,12 @@ public static class ConfigManager
9695
9796 private static List < FilterProfile > _profiles = new List < FilterProfile > ( ) ;
9897
98+ // 缓存属性元数据,避免 Save() 每次都反射查找
99+ private static readonly ConcurrentDictionary < string , PropertyInfo ? > _propertyCache = new ( ) ;
100+
101+ // 保护并发 Save / _profiles 访问
102+ private static readonly object _syncLock = new ( ) ;
103+
99104 public static void Load ( )
100105 {
101106 try
@@ -236,20 +241,29 @@ public static void GetAnimationSpeedsForOverlay(out double trailSpeed, out doubl
236241 }
237242 }
238243
239- public static List < FilterProfile > GetProfiles ( ) => _profiles ;
244+ public static List < FilterProfile > GetProfiles ( )
245+ {
246+ lock ( _syncLock ) { return [ .. _profiles ] ; }
247+ }
240248
241249 public static FilterProfile ? GetActiveProfile ( )
242250 {
243- return _profiles . FirstOrDefault ( p => p . Id == ActiveProfileId ) ?? _profiles . FirstOrDefault ( ) ;
251+ lock ( _syncLock )
252+ {
253+ return _profiles . FirstOrDefault ( p => p . Id == ActiveProfileId ) ?? _profiles . FirstOrDefault ( ) ;
254+ }
244255 }
245256
246257 public static void SaveProfiles ( List < FilterProfile > profiles , string activeId )
247258 {
248- _profiles = profiles ;
249- ActiveProfileId = activeId ;
250- string json = System . Text . Json . JsonSerializer . Serialize ( _profiles ) ;
251- Save ( "FilterProfiles" , json ) ;
252- Save ( "ActiveProfileId" , activeId ) ;
259+ lock ( _syncLock )
260+ {
261+ _profiles = profiles ;
262+ ActiveProfileId = activeId ;
263+ string json = System . Text . Json . JsonSerializer . Serialize ( _profiles ) ;
264+ Save ( "FilterProfiles" , json ) ;
265+ Save ( "ActiveProfileId" , activeId ) ;
266+ }
253267 }
254268
255269 /// 将选中的视觉表现项恢复默认值并写入注册表
@@ -303,8 +317,9 @@ public static void Save(string name, object value)
303317 {
304318 try
305319 {
306- using ( RegistryKey key = Registry . CurrentUser . CreateSubKey ( RegPath ) )
320+ lock ( _syncLock )
307321 {
322+ using RegistryKey key = Registry . CurrentUser . CreateSubKey ( RegPath ) ;
308323 if ( value is Enum enumValue )
309324 {
310325 key . SetValue ( name , enumValue . ToString ( ) ) ;
@@ -314,7 +329,7 @@ public static void Save(string name, object value)
314329 key . SetValue ( name , value ) ;
315330 }
316331
317- var prop = typeof ( ConfigManager ) . GetProperty ( name ) ;
332+ var prop = _propertyCache . GetOrAdd ( name , n => typeof ( ConfigManager ) . GetProperty ( n ) ) ;
318333 if ( prop != null )
319334 {
320335 object propertyValue = value ;
@@ -487,48 +502,51 @@ public static void ResetAndClear()
487502 {
488503 try
489504 {
490- Registry . CurrentUser . DeleteSubKeyTree ( RegPath , false ) ;
491-
492- string oldJson = System . IO . Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "config.json" ) ;
493- if ( System . IO . File . Exists ( oldJson ) )
505+ lock ( _syncLock )
494506 {
495- System . IO . File . Delete ( oldJson ) ;
496- }
507+ Registry . CurrentUser . DeleteSubKeyTree ( RegPath , false ) ;
497508
498- ParticleColor = "45,175,255" ;
499- IsEffectEnabled = true ;
500- AutoStart = false ;
501- AgreedToPrivacy = false ;
502- EnableTelemetry = false ;
503- TotalClicks = 0 ;
504- LastNoticeContent = "" ;
505- EnableAlwaysTrailEffect = false ;
506- StartSilent = false ;
507- RunAsAdmin = false ;
508- EffectScale = 1.5 ;
509- EffectOpacity = 1.0 ;
510- EffectSpeed = 1.0 ;
511- UseLinkedAnimationSpeed = true ;
512- TrailAnimationSpeed = 1.0 ;
513- ClickAnimationSpeed = 1.0 ;
514- TrailRefreshRate = 40 ;
515- EnableEnvironmentFilter = false ;
516- HideInFullscreen = true ;
517- ShowEffectOnDesktop = true ;
518- FilterProfiles = "" ;
519- ActiveProfileId = "" ;
520- _profiles . Clear ( ) ;
521- IsTouchscreenMode = false ;
522- ClickTriggerType = 0 ;
523- EnableMiddleClickTrigger = false ;
524- ScreenshotCompatibilityMode = false ;
525- EnabledScreenIds = "" ;
526- ScreenSelections = "" ;
527- UiLanguage = "" ;
528- NetworkRegion = NetworkRegionOption . Auto ;
529- SidebarBackgroundImagePath = "" ;
530- TelemetryClientId = "" ;
531- LastTelemetrySentUtc = "" ;
509+ string oldJson = System . IO . Path . Combine ( AppDomain . CurrentDomain . BaseDirectory , "config.json" ) ;
510+ if ( System . IO . File . Exists ( oldJson ) )
511+ {
512+ System . IO . File . Delete ( oldJson ) ;
513+ }
514+
515+ ParticleColor = "45,175,255" ;
516+ IsEffectEnabled = true ;
517+ AutoStart = false ;
518+ AgreedToPrivacy = false ;
519+ EnableTelemetry = false ;
520+ TotalClicks = 0 ;
521+ LastNoticeContent = "" ;
522+ EnableAlwaysTrailEffect = false ;
523+ StartSilent = false ;
524+ RunAsAdmin = false ;
525+ EffectScale = 1.5 ;
526+ EffectOpacity = 1.0 ;
527+ EffectSpeed = 1.0 ;
528+ UseLinkedAnimationSpeed = true ;
529+ TrailAnimationSpeed = 1.0 ;
530+ ClickAnimationSpeed = 1.0 ;
531+ TrailRefreshRate = 40 ;
532+ EnableEnvironmentFilter = false ;
533+ HideInFullscreen = true ;
534+ ShowEffectOnDesktop = true ;
535+ FilterProfiles = "" ;
536+ ActiveProfileId = "" ;
537+ _profiles . Clear ( ) ;
538+ IsTouchscreenMode = false ;
539+ ClickTriggerType = 0 ;
540+ EnableMiddleClickTrigger = false ;
541+ ScreenshotCompatibilityMode = false ;
542+ EnabledScreenIds = "" ;
543+ ScreenSelections = "" ;
544+ UiLanguage = "" ;
545+ NetworkRegion = NetworkRegionOption . Auto ;
546+ SidebarBackgroundImagePath = "" ;
547+ TelemetryClientId = "" ;
548+ LastTelemetrySentUtc = "" ;
549+ }
532550 }
533551 catch ( Exception ex )
534552 {
0 commit comments