1212using System . Diagnostics . CodeAnalysis ;
1313using System . IO ;
1414using System . Linq ;
15+ using System . Threading ;
1516using System . Threading . Tasks ;
16- using System . Threading . Tasks . Dataflow ;
1717using ImageUI = Microsoft . UI . Xaml . Controls . Image ;
1818// ReSharper disable PartialTypeWithSinglePart
1919// ReSharper disable AsyncVoidMethod
@@ -49,9 +49,9 @@ internal enum MediaType
4949 [ ".mp4" , ".mov" , ".mkv" , ".webm" , ".avi" , ".gif" ] ;
5050
5151 private static FrameworkElement ? _parentUI ;
52- private ImageUI ? _bgImageBackground ;
53- private ImageUI ? _bgImageBackgroundLast ;
54- private MediaPlayerElement ? _bgMediaPlayerBackground ;
52+ private ImageUI ? _bgImageBackground ;
53+ private ImageUI ? _bgImageBackgroundLast ;
54+ private MediaPlayerElement ? _bgMediaPlayerBackground ;
5555
5656 private Grid ? _bgAcrylicMask ;
5757 private Grid ? _bgOverlayTitleBar ;
@@ -70,28 +70,23 @@ internal enum MediaType
7070
7171 private static FileStream ? _alternativeFileStream ;
7272
73- private delegate ValueTask AssignDefaultAction < in T > ( T element ) where T : class ;
74- internal delegate void ThrowExceptionAction ( Exception element ) ;
75- internal static ActionBlock < Task > ? SharedActionBlockQueue = new ( async action =>
76- {
77- try
78- {
79- await action ;
80- }
81- catch ( Exception ex )
82- {
83- _parentUI ? . DispatcherQueue . TryEnqueue ( ( ) =>
84- ErrorSender . SendException ( ex ) ) ;
85- }
86- } ,
87- new ExecutionDataflowBlockOptions
88- {
89- EnsureOrdered = true ,
90- MaxMessagesPerTask = 1 ,
91- MaxDegreeOfParallelism = 1 ,
92- BoundedCapacity = 1 ,
93- TaskScheduler = TaskScheduler . Current
94- } ) ;
73+ private delegate ValueTask AssignDefaultAction < in T > ( T element ) where T : class ;
74+ internal delegate void ThrowExceptionAction ( Exception element ) ;
75+
76+ private static bool _isOnQueue ;
77+ internal static async void RunQueuedTask ( Task task )
78+ {
79+ while ( _isOnQueue )
80+ {
81+ await Task . Delay ( 100 ) ;
82+ }
83+
84+ Interlocked . Exchange ( ref _isOnQueue , true ) ;
85+ await task ;
86+ Interlocked . Exchange ( ref _isOnQueue , false ) ;
87+ }
88+
89+ internal static void RunQueuedTask ( Action action ) => RunQueuedTask ( Task . Factory . StartNew ( action ) ) ;
9590
9691 /// <summary>
9792 /// Attach and register the <see cref="Grid" /> of the page to be assigned with background utility.
@@ -319,19 +314,12 @@ private void EnsureCurrentMediaPlayerRegistered()
319314 /// <param name="actionAfterLoaded">Action to do after background is loaded</param>
320315 /// <exception cref="FormatException">Throws if the background file is not supported</exception>
321316 /// <exception cref="NullReferenceException">Throws if some instances aren't yet initialized</exception>
322- internal async void LoadBackground ( string mediaPath ,
323- bool isRequestInit = false ,
324- bool isForceRecreateCache = false ,
325- ThrowExceptionAction ? throwAction = null ,
326- Action ? actionAfterLoaded = null )
327- {
328- while ( ! await SharedActionBlockQueue ? . SendAsync ( LoadBackgroundInner ( mediaPath , isRequestInit , isForceRecreateCache , throwAction , actionAfterLoaded ) ) ! )
329- {
330- // Delay the invoke 1/4 second and wait until the action can
331- // be sent again.
332- await Task . Delay ( 250 ) ;
333- }
334- }
317+ internal void LoadBackground ( string mediaPath ,
318+ bool isRequestInit = false ,
319+ bool isForceRecreateCache = false ,
320+ ThrowExceptionAction ? throwAction = null ,
321+ Action ? actionAfterLoaded = null )
322+ => RunQueuedTask ( LoadBackgroundInner ( mediaPath , isRequestInit , isForceRecreateCache , throwAction , actionAfterLoaded ) ) ;
335323
336324 private async Task LoadBackgroundInner ( string mediaPath , bool isRequestInit = false ,
337325 bool isForceRecreateCache = false , ThrowExceptionAction ? throwAction = null ,
@@ -340,11 +328,13 @@ private async Task LoadBackgroundInner(string mediaPath, bool
340328 if ( mediaPath . Equals ( CurrentAppliedMediaPath , StringComparison . OrdinalIgnoreCase ) )
341329 return ;
342330
331+ Interlocked . Exchange ( ref CurrentAppliedMediaPath , mediaPath ) ;
332+
343333 try
344334 {
345335 while ( ! _isCurrentRegistered )
346336 {
347- await Task . Delay ( 250 , _cancellationToken ? . Token ?? default ) ;
337+ await Task . Delay ( 250 , _cancellationToken ? . Token ?? CancellationToken . None ) ;
348338 }
349339
350340 EnsureCurrentImageRegistered ( ) ;
@@ -401,8 +391,6 @@ private async Task LoadBackgroundInner(string mediaPath, bool
401391
402392 CurrentAppliedMediaType = mediaType ;
403393 actionAfterLoaded ? . Invoke ( ) ;
404-
405- CurrentAppliedMediaPath = mediaPath ;
406394 }
407395 catch ( Exception ex )
408396 {
0 commit comments