internal TValue Invoke <TValue>(string identifier, long targetInstanceId, params object?[]?args) { var resultJson = InvokeJS( identifier, JsonSerializer.Serialize(args, JsonSerializerOptions), JSCallResultTypeHelper.FromGeneric <TValue>(), targetInstanceId); if (resultJson is null) { return(default);
internal TValue Invoke <[DynamicallyAccessedMembers(JsonSerialized)] TValue>(string identifier, long targetInstanceId, params object?[]?args) { var resultJson = InvokeJS( identifier, JsonSerializer.Serialize(args, JsonSerializerOptions), JSCallResultTypeHelper.FromGeneric <TValue>(), targetInstanceId); // While the result of deserialization could be null, we're making a // quality of life decision and letting users explicitly determine if they expect // null by specifying TValue? as the expected return type. if (resultJson is null) { return(default !);
internal ValueTask <TValue> InvokeAsync <TValue>( long targetInstanceId, string identifier, CancellationToken cancellationToken, object?[]?args) { var taskId = Interlocked.Increment(ref _nextPendingTaskId); var tcs = new TaskCompletionSource <TValue>(); if (cancellationToken.CanBeCanceled) { _cancellationRegistrations[taskId] = cancellationToken.Register(() => { tcs.TrySetCanceled(cancellationToken); CleanupTasksAndRegistrations(taskId); }); } _pendingTasks[taskId] = tcs; try { if (cancellationToken.IsCancellationRequested) { tcs.TrySetCanceled(cancellationToken); CleanupTasksAndRegistrations(taskId); return(new ValueTask <TValue>(tcs.Task)); } var argsJson = args?.Any() == true? JsonSerializer.Serialize(args, JsonSerializerOptions) : null; var resultType = JSCallResultTypeHelper.FromGeneric <TValue>(); BeginInvokeJS(taskId, identifier, argsJson, resultType, targetInstanceId); return(new ValueTask <TValue>(tcs.Task)); } catch { CleanupTasksAndRegistrations(taskId); throw; } }