33
44using System ;
55using System . Collections . Concurrent ;
6- using System . Collections . Generic ;
76using System . Diagnostics ;
87using System . Diagnostics . CodeAnalysis ;
9- using System . IO ;
108using System . Text . Json ;
119using System . Threading ;
1210using System . Threading . Tasks ;
@@ -22,16 +20,16 @@ public abstract partial class JSRuntime : IJSRuntime
2220 {
2321 private long _nextObjectReferenceId = 0 ; // 0 signals no object, but we increment prior to assignment. The first tracked object should have id 1
2422 private long _nextPendingTaskId = 1 ; // Start at 1 because zero signals "no response needed"
25- private readonly ConcurrentDictionary < long , object > _pendingTasks = new ConcurrentDictionary < long , object > ( ) ;
26- private readonly ConcurrentDictionary < long , IDotNetObjectReference > _trackedRefsById = new ConcurrentDictionary < long , IDotNetObjectReference > ( ) ;
27- private readonly ConcurrentDictionary < long , CancellationTokenRegistration > _cancellationRegistrations =
28- new ConcurrentDictionary < long , CancellationTokenRegistration > ( ) ;
23+ private readonly ConcurrentDictionary < long , object > _pendingTasks = new ( ) ;
24+ private readonly ConcurrentDictionary < long , IDotNetObjectReference > _trackedRefsById = new ( ) ;
25+ private readonly ConcurrentDictionary < long , CancellationTokenRegistration > _cancellationRegistrations = new ( ) ;
2926
3027 /// <summary>
3128 /// Initializes a new instance of <see cref="JSRuntime"/>.
3229 /// </summary>
3330 protected JSRuntime ( )
3431 {
32+ ByteArrayJsonConverter = new ByteArrayJsonConverter ( ) ;
3533 JsonSerializerOptions = new JsonSerializerOptions
3634 {
3735 MaxDepth = 32 ,
@@ -41,7 +39,7 @@ protected JSRuntime()
4139 {
4240 new DotNetObjectReferenceJsonConverterFactory ( this ) ,
4341 new JSObjectReferenceJsonConverter ( this ) ,
44- new ByteArrayJsonConverter ( this ) ,
42+ ByteArrayJsonConverter ,
4543 }
4644 } ;
4745 }
@@ -52,19 +50,14 @@ protected JSRuntime()
5250 protected internal JsonSerializerOptions JsonSerializerOptions { get ; }
5351
5452 /// <summary>
55- /// Gets or sets the default timeout for asynchronous JavaScript calls .
53+ /// Gets the <see cref="Infrastructure.ByteArrayJsonConverter"/> used to serialize and deserialize byte arrays from the interop payloads .
5654 /// </summary>
57- protected TimeSpan ? DefaultAsyncTimeout { get ; set ; }
55+ internal ByteArrayJsonConverter ByteArrayJsonConverter { get ; }
5856
5957 /// <summary>
60- /// Contains the combined byte array(s) being serialized.
61- /// </summary>
62- internal readonly List < byte [ ] > ByteArraysToSerialize = new ( ) ;
63-
64- /// <summary>
65- /// Contains the combined byte array(s) being deserialized.
58+ /// Gets or sets the default timeout for asynchronous JavaScript calls.
6659 /// </summary>
67- internal byte [ ] [ ] ? ByteArraysToDeserialize { get ; set ; }
60+ protected TimeSpan ? DefaultAsyncTimeout { get ; set ; }
6861
6962 /// <summary>
7063 /// Invokes the specified JavaScript function asynchronously.
@@ -135,12 +128,12 @@ protected JSRuntime()
135128 }
136129
137130 var serializedArgs = args is not null && args . Length != 0 ?
138- SerializeArgs ( args ) :
131+ DotNetDispatcher . SerializeArgs ( this , args ) :
139132 new SerializedArgs ( null , null ) ;
140133 var resultType = JSCallResultTypeHelper . FromGeneric < TValue > ( ) ;
141134
142135
143- BeginInvokeJS ( taskId , identifier , serializedArgs . ArgsJson , serializedArgs . ByteArrays , resultType , targetInstanceId ) ;
136+ BeginInvokeJS ( taskId , identifier , serializedArgs , resultType , targetInstanceId ) ;
144137
145138 return new ValueTask < TValue > ( tcs . Task ) ;
146139 }
@@ -160,44 +153,24 @@ private void CleanupTasksAndRegistrations(long taskId)
160153 }
161154 }
162155
163- /// <summary>
164- /// Serialize the args to a json string, with the byte arrays
165- /// extracted out for seperate transmission.
166- /// </summary>
167- /// <param name="args">Arguments to be converted to json.</param>
168- /// <returns>
169- /// A tuple of the json string and an array containing the extracted
170- /// byte arrays from the args.
171- /// </returns>
172- protected internal SerializedArgs SerializeArgs ( object ? args )
173- {
174- ByteArraysToSerialize . Clear ( ) ;
175- var serializedArgs = JsonSerializer . Serialize ( args , JsonSerializerOptions ) ;
176- var byteArrays = ByteArraysToSerialize . ToArray ( ) ;
177-
178- return new ( serializedArgs , byteArrays ) ;
179- }
180-
181156 /// <summary>
182157 /// Begins an asynchronous function invocation.
183158 /// </summary>
184159 /// <param name="taskId">The identifier for the function invocation, or zero if no async callback is required.</param>
185160 /// <param name="identifier">The identifier for the function to invoke.</param>
186- /// <param name="argsJson">A JSON representation of the arguments.</param>
187- /// <param name="byteArrays">Byte array data extracted from the arguments for direct transfer.</param>
188- protected virtual void BeginInvokeJS ( long taskId , string identifier , string ? argsJson , byte [ ] [ ] ? byteArrays )
189- => BeginInvokeJS ( taskId , identifier , argsJson , byteArrays , JSCallResultType . Default , 0 ) ;
161+ /// <param name="serializedArgs">The serialized args containing the JSON representation along with the extracted byte arrays.</param>
162+ protected virtual void BeginInvokeJS ( long taskId , string identifier , SerializedArgs serializedArgs )
163+ => BeginInvokeJS ( taskId , identifier , serializedArgs , JSCallResultType . Default , 0 ) ;
190164
191165 /// <summary>
192166 /// Begins an asynchronous function invocation.
193167 /// </summary>
194168 /// <param name="taskId">The identifier for the function invocation, or zero if no async callback is required.</param>
195169 /// <param name="identifier">The identifier for the function to invoke.</param>
196- /// <param name="argsJson">A JSON representation of the arguments.</param>
197- /// <param name="byteArrays">Byte array data extracted from the arguments for direct transfer.</param>
170+ /// <param name="serializedArgs">The serialized args containing the JSON representation along with the extracted byte arrays.</param>
198171 /// <param name="resultType">The type of result expected from the invocation.</param>
199172 /// <param name="targetInstanceId">The instance ID of the target JS object.</param>
200- protected abstract void BeginInvokeJS ( long taskId , string identifier , string ? argsJson , byte [ ] [ ] ? byteArrays , JSCallResultType resultType , long targetInstanceId ) ;
173+ protected abstract void BeginInvokeJS ( long taskId , string identifier , SerializedArgs serializedArgs , JSCallResultType resultType , long targetInstanceId ) ;
201174
202175 /// <summary>
203176 /// Completes an async JS interop call from JavaScript to .NET
@@ -226,10 +199,10 @@ internal void EndInvokeJS(long taskId, bool succeeded, ref Utf8JsonReader jsonRe
226199 {
227200 var resultType = TaskGenericsUtil . GetTaskCompletionSourceResultType ( tcs ) ;
228201
229- ByteArraysToDeserialize = byteArrays ;
202+ ByteArrayJsonConverter . ByteArraysToDeserialize = byteArrays ;
230203 var result = JsonSerializer . Deserialize ( ref jsonReader , resultType , JsonSerializerOptions ) ;
231204 TaskGenericsUtil . SetTaskCompletionSourceResult ( tcs , result ) ;
232- ByteArraysToDeserialize = null ;
205+ ByteArrayJsonConverter . ByteArraysToDeserialize = null ;
233206 }
234207 else
235208 {
0 commit comments