1
- using System ;
1
+ #nullable enable
2
+
3
+ using System ;
2
4
using System . Collections . Generic ;
3
5
using System . Collections . Immutable ;
4
6
using System . ComponentModel ;
@@ -87,7 +89,7 @@ public static bool InvokeJSUnmarshalled(string functionIdentifier, IntPtr arg0)
87
89
/// Invoke a Javascript method using unmarshaled conversion.
88
90
/// </summary>
89
91
/// <param name="functionIdentifier">A function identifier name</param>
90
- internal static bool InvokeJSUnmarshalled ( string functionIdentifier , IntPtr arg0 , out Exception exception )
92
+ internal static bool InvokeJSUnmarshalled ( string functionIdentifier , IntPtr arg0 , out Exception ? exception )
91
93
{
92
94
if ( _trace . IsEnabled )
93
95
{
@@ -102,7 +104,7 @@ internal static bool InvokeJSUnmarshalled(string functionIdentifier, IntPtr arg0
102
104
}
103
105
}
104
106
105
- private static bool InnerInvokeJSUnmarshalled ( string functionIdentifier , IntPtr arg0 , out Exception exception )
107
+ private static bool InnerInvokeJSUnmarshalled ( string functionIdentifier , IntPtr arg0 , out Exception ? exception )
106
108
{
107
109
exception = null ;
108
110
var methodId = GetMethodId ( functionIdentifier ) ;
@@ -115,7 +117,7 @@ private static bool InnerInvokeJSUnmarshalled(string functionIdentifier, IntPtr
115
117
{
116
118
_trace . WriteEvent (
117
119
TraceProvider . InvokeException ,
118
- new object [ ] { functionIdentifier , exception . ToString ( ) }
120
+ new object [ ] { functionIdentifier , exceptionMessage }
119
121
) ;
120
122
}
121
123
@@ -169,7 +171,7 @@ private static bool InnerInvokeJSUnmarshalled(string functionIdentifier, IntPtr
169
171
/// <summary>
170
172
/// Provides an override for javascript invokes.
171
173
/// </summary>
172
- public static Func < string , string > InvokeJSOverride ;
174
+ public static Func < string , string > ? InvokeJSOverride ;
173
175
174
176
public static string InvokeJS ( string str )
175
177
{
@@ -222,7 +224,7 @@ private static string InnerInvokeJS(String str)
222
224
return result ;
223
225
}
224
226
225
- public static object GetObjectFromGcHandle ( string intPtr )
227
+ public static object ? GetObjectFromGcHandle ( string intPtr )
226
228
{
227
229
var ptr = Marshal . StringToHGlobalAuto ( intPtr ) ;
228
230
var handle = GCHandle . FromIntPtr ( ptr ) ;
@@ -268,74 +270,81 @@ public static string InvokeJSWithInterop(FormattableString formattable)
268
270
return InvokeJS ( command ) ;
269
271
}
270
272
271
- private static readonly Dictionary < long , TaskCompletionSource < string > > _asyncWaitingList = new Dictionary < long , TaskCompletionSource < string > > ( ) ;
273
+ private static readonly Dictionary < long , ( TaskCompletionSource < string > task , CancellationTokenRegistration ctReg ) > _asyncWaitingList
274
+ = new Dictionary < long , ( TaskCompletionSource < string > task , CancellationTokenRegistration ctReg ) > ( ) ;
272
275
273
276
private static long _nextAsync ;
274
277
278
+
279
+ /// <summary>
280
+ /// DO NOT USE, use overload with CancellationToken instead
281
+ /// </remarks>
282
+ public static Task < string > InvokeAsync ( string promiseCode )
283
+ => InvokeAsync ( promiseCode , CancellationToken . None ) ;
284
+
275
285
/// <summary>
276
286
/// Invoke async javascript code.
277
287
/// </summary>
278
288
/// <remarks>
279
289
/// The javascript code is expected to return a Promise<string>
280
290
/// </remarks>
281
- public static Task < string > InvokeAsync ( string promiseCode )
291
+ public static Task < string > InvokeAsync ( string promiseCode , CancellationToken ct )
282
292
{
283
- var id = Interlocked . Increment ( ref _nextAsync ) ;
284
-
293
+ var handle = Interlocked . Increment ( ref _nextAsync ) ;
285
294
var tcs = new TaskCompletionSource < string > ( ) ;
295
+ var ctReg = ct . CanBeCanceled ? ct . Register ( ( ) => RemoveAsyncTask ( handle ) ? . TrySetCanceled ( ) ) : default ;
286
296
287
297
lock ( _asyncWaitingList )
288
298
{
289
- _asyncWaitingList [ id ] = tcs ;
299
+ _asyncWaitingList [ handle ] = ( tcs , ctReg ) ;
290
300
}
291
301
292
302
var js = new [ ]
293
303
{
294
304
"const __f = ()=>" ,
295
305
promiseCode ,
296
306
";\n Uno.UI.Interop.AsyncInteropHelper.Invoke(" ,
297
- id . ToStringInvariant ( ) ,
307
+ handle . ToStringInvariant ( ) ,
298
308
", __f);"
299
309
} ;
300
310
301
311
try
302
312
{
303
-
304
313
WebAssemblyRuntime . InvokeJS ( string . Concat ( js ) ) ;
314
+
315
+ return tcs . Task ;
305
316
}
306
317
catch ( Exception ex )
307
318
{
319
+ RemoveAsyncTask ( handle ) ;
320
+
308
321
return Task . FromException < string > ( ex ) ;
309
322
}
310
-
311
- return tcs . Task ;
312
323
}
313
324
314
325
[ EditorBrowsable ( EditorBrowsableState . Never ) ]
315
326
public static void DispatchAsyncResult ( long handle , string result )
316
- {
317
- lock ( _asyncWaitingList )
318
- {
319
- if ( _asyncWaitingList . TryGetValue ( handle , out var tcs ) )
320
- {
321
- tcs . TrySetResult ( result ) ;
322
- _asyncWaitingList . Remove ( handle ) ;
323
- }
324
- }
325
- }
327
+ => RemoveAsyncTask ( handle ) ? . TrySetResult ( result ) ;
326
328
327
329
[ EditorBrowsable ( EditorBrowsableState . Never ) ]
328
330
public static void DispatchAsyncError ( long handle , string error )
331
+ => RemoveAsyncTask ( handle ) ? . TrySetException ( new ApplicationException ( error ) ) ;
332
+
333
+ private static TaskCompletionSource < string > ? RemoveAsyncTask ( long handle )
329
334
{
335
+ ( TaskCompletionSource < string > task , CancellationTokenRegistration ctReg ) listener ;
330
336
lock ( _asyncWaitingList )
331
337
{
332
- if ( _asyncWaitingList . TryGetValue ( handle , out var tcs ) )
338
+ if ( ! _asyncWaitingList . TryGetValue ( handle , out listener ) )
333
339
{
334
- var exception = new ApplicationException ( error ) ;
335
- tcs . TrySetException ( exception ) ;
336
- _asyncWaitingList . Remove ( handle ) ;
340
+ return default ;
337
341
}
342
+ _asyncWaitingList . Remove ( handle ) ;
338
343
}
344
+
345
+ listener . ctReg . Dispose ( ) ;
346
+
347
+ return listener . task ;
339
348
}
340
349
341
350
[ Pure ]
@@ -417,7 +426,7 @@ bool NeedsEscape(string s2)
417
426
}
418
427
}
419
428
420
- private static IDisposable WritePropertyEventTrace ( int startEventId , int stopEventId , string script )
429
+ private static IDisposable ? WritePropertyEventTrace ( int startEventId , int stopEventId , string script )
421
430
{
422
431
if ( _trace . IsEnabled )
423
432
{
0 commit comments