@@ -2,11 +2,12 @@ namespace LoreSoft.Blazor.Controls.Utilities;
22
33public static class ConstrainedAction
44{
5- public static Action < T > Debounce < T > ( Action < T > action , TimeSpan interval )
5+ public static Action < T > Debounce < T > ( Action < T > action , TimeSpan ? delay = null )
66 {
77 if ( action == null )
88 throw new ArgumentNullException ( nameof ( action ) ) ;
99
10+ var interval = delay ?? TimeSpan . FromMilliseconds ( 800 ) ;
1011 var last = 0 ;
1112
1213 return ( T arguments ) =>
@@ -20,11 +21,68 @@ public static Action<T> Debounce<T>(Action<T> action, TimeSpan interval)
2021 } ;
2122 }
2223
23- public static Action < T > Throttle < T > ( Action < T > action , TimeSpan interval )
24+ public static Action Debounce ( Action action , TimeSpan ? delay = null )
2425 {
2526 if ( action == null )
2627 throw new ArgumentNullException ( nameof ( action ) ) ;
2728
29+ var interval = delay ?? TimeSpan . FromMilliseconds ( 800 ) ;
30+ var last = 0 ;
31+
32+ return ( ) =>
33+ {
34+ var current = Interlocked . Increment ( ref last ) ;
35+ Task . Delay ( interval ) . ContinueWith ( task =>
36+ {
37+ if ( current == last )
38+ action ( ) ;
39+ } ) ;
40+ } ;
41+ }
42+
43+
44+ public static Func < T , Task > Debounce < T > ( Func < T , Task > action , TimeSpan ? delay = null )
45+ {
46+ if ( action == null )
47+ throw new ArgumentNullException ( nameof ( action ) ) ;
48+
49+ var interval = delay ?? TimeSpan . FromMilliseconds ( 800 ) ;
50+ var last = 0 ;
51+
52+ return async ( T arguments ) =>
53+ {
54+ var current = Interlocked . Increment ( ref last ) ;
55+ await Task . Delay ( interval ) ;
56+ if ( current == last )
57+ await action ( arguments ) ;
58+ } ;
59+ }
60+
61+ public static Func < Task > Debounce ( Func < Task > action , TimeSpan ? delay = null )
62+ {
63+ if ( action == null )
64+ throw new ArgumentNullException ( nameof ( action ) ) ;
65+
66+ var interval = delay ?? TimeSpan . FromMilliseconds ( 800 ) ;
67+ var last = 0 ;
68+
69+ return async ( ) =>
70+ {
71+ var current = Interlocked . Increment ( ref last ) ;
72+ await Task . Delay ( interval ) ;
73+ if ( current == last )
74+ await action ( ) ;
75+ } ;
76+ }
77+
78+
79+ public static Action < T > Throttle < T > ( Action < T > action , TimeSpan ? delay = null )
80+ {
81+ if ( action == null )
82+ throw new ArgumentNullException ( nameof ( action ) ) ;
83+
84+ var interval = delay ?? TimeSpan . FromMilliseconds ( 800 ) ;
85+
2886 Task task = null ;
2987 var locker = new object ( ) ;
3088 T arguments = default ;
@@ -48,4 +106,34 @@ public static Action<T> Throttle<T>(Action<T> action, TimeSpan interval)
48106 }
49107 } ;
50108 }
109+
110+ public static Action Throttle ( Action action , TimeSpan ? delay = null )
111+ {
112+ if ( action == null )
113+ throw new ArgumentNullException ( nameof ( action ) ) ;
114+
115+ var interval = delay ?? TimeSpan . FromMilliseconds ( 800 ) ;
116+
117+ Task task = null ;
118+ var locker = new object ( ) ;
119+
120+ return ( ) =>
121+ {
122+ if ( task != null )
123+ return ;
124+
125+ lock ( locker )
126+ {
127+ if ( task != null )
128+ return ;
129+
130+ task = Task . Delay ( interval ) . ContinueWith ( t =>
131+ {
132+ action ( ) ;
133+ task = null ;
134+ } ) ;
135+ }
136+ } ;
137+ }
138+
51139}
0 commit comments