public async Task InitializeAsync(CancellationToken cancellationToken) { await Renderer.InvokeAsync(async() => { try { SetCurrentCircuitHost(this); _initialized = true; // We're ready to accept incoming JSInterop calls from here on await OnCircuitOpenedAsync(cancellationToken); await OnConnectionUpAsync(cancellationToken); // We add the root components *after* the circuit is flagged as open. // That's because AddComponentAsync waits for quiescence, which can take // arbitrarily long. In the meantime we might need to be receiving and // processing incoming JSInterop calls or similar. for (var i = 0; i < Descriptors.Count; i++) { var(componentType, domElementSelector, prerendered) = Descriptors[i]; if (!prerendered) { await Renderer.AddComponentAsync(componentType, domElementSelector); } } } catch (Exception ex) { // We have to handle all our own errors here, because the upstream caller // has to fire-and-forget this Renderer_UnhandledException(this, ex); } }); }
public async Task InitializeAsync(CancellationToken cancellationToken) { await Renderer.InvokeAsync(async() => { SetCurrentCircuitHost(this); var builder = new ServerSideComponentsApplicationBuilder(Services); _configure(builder); for (var i = 0; i < builder.Entries.Count; i++) { var(componentType, domElementSelector) = builder.Entries[i]; await Renderer.AddComponentAsync(componentType, domElementSelector); } for (var i = 0; i < _circuitHandlers.Length; i++) { await _circuitHandlers[i].OnCircuitOpenedAsync(Circuit, cancellationToken); } for (var i = 0; i < _circuitHandlers.Length; i++) { await _circuitHandlers[i].OnConnectionUpAsync(Circuit, cancellationToken); } }); _initialized = true; }
public async Task InitializeAsync(CancellationToken cancellationToken) { await Renderer.InvokeAsync(async() => { SetCurrentCircuitHost(this); for (var i = 0; i < Descriptors.Count; i++) { var(componentType, domElementSelector) = Descriptors[i]; await Renderer.AddComponentAsync(componentType, domElementSelector); } for (var i = 0; i < _circuitHandlers.Length; i++) { await _circuitHandlers[i].OnCircuitOpenedAsync(Circuit, cancellationToken); } for (var i = 0; i < _circuitHandlers.Length; i++) { await _circuitHandlers[i].OnConnectionUpAsync(Circuit, cancellationToken); } }); _initialized = true; }
// InitializeAsync is used in a fire-and-forget context, so it's responsible for its own // error handling. public Task InitializeAsync(ProtectedPrerenderComponentApplicationStore store, CancellationToken cancellationToken) { Log.InitializationStarted(_logger); return(Renderer.Dispatcher.InvokeAsync(async() => { if (_initialized) { throw new InvalidOperationException("The circuit host is already initialized."); } try { _initialized = true; // We're ready to accept incoming JSInterop calls from here on await OnCircuitOpenedAsync(cancellationToken); await OnConnectionUpAsync(cancellationToken); // Here, we add each root component but don't await the returned tasks so that the // components can be processed in parallel. var count = Descriptors.Count; var pendingRenders = new Task[count]; for (var i = 0; i < count; i++) { var(componentType, parameters, sequence) = Descriptors[i]; pendingRenders[i] = Renderer.AddComponentAsync(componentType, parameters, sequence.ToString(CultureInfo.InvariantCulture)); } // Now we wait for all components to finish rendering. await Task.WhenAll(pendingRenders); // At this point all components have successfully produced an initial render and we can clear the contents of the component // application state store. This ensures the memory that was not used during the initial render of these components gets // reclaimed since no-one else is holding on to it any longer. store.ExistingState.Clear(); Log.InitializationSucceeded(_logger); } catch (Exception ex) { // Report errors asynchronously. InitializeAsync is designed not to throw. Log.InitializationFailed(_logger, ex); UnhandledException?.Invoke(this, new UnhandledExceptionEventArgs(ex, isTerminating: false)); await TryNotifyClientErrorAsync(Client, GetClientErrorMessage(ex), ex); } })); }
// InitializeAsync is used in a fire-and-forget context, so it's responsible for its own // error handling. public Task InitializeAsync(ProtectedPrerenderComponentApplicationStore store, CancellationToken cancellationToken) { Log.InitializationStarted(_logger); return(Renderer.Dispatcher.InvokeAsync(async() => { if (_initialized) { throw new InvalidOperationException("The circuit host is already initialized."); } try { _initialized = true; // We're ready to accept incoming JSInterop calls from here on await OnCircuitOpenedAsync(cancellationToken); await OnConnectionUpAsync(cancellationToken); // We add the root components *after* the circuit is flagged as open. // That's because AddComponentAsync waits for quiescence, which can take // arbitrarily long. In the meantime we might need to be receiving and // processing incoming JSInterop calls or similar. var count = Descriptors.Count; for (var i = 0; i < count; i++) { var(componentType, parameters, sequence) = Descriptors[i]; await Renderer.AddComponentAsync(componentType, parameters, sequence.ToString(CultureInfo.InvariantCulture)); } // At this point all components have successfully produced an initial render and we can clear the contents of the component // application state store. This ensures the memory that was not used during the initial render of these components gets // reclaimed since no-one else is holding on to it any longer. store.ExistingState.Clear(); Log.InitializationSucceeded(_logger); } catch (Exception ex) { // Report errors asynchronously. InitializeAsync is designed not to throw. Log.InitializationFailed(_logger, ex); UnhandledException?.Invoke(this, new UnhandledExceptionEventArgs(ex, isTerminating: false)); await TryNotifyClientErrorAsync(Client, GetClientErrorMessage(ex), ex); } })); }
// InitializeAsync is used in a fire-and-forget context, so it's responsible for its own // error handling. public Task InitializeAsync(CancellationToken cancellationToken) { Log.InitializationStarted(_logger); return(Renderer.Dispatcher.InvokeAsync(async() => { if (_initialized) { throw new InvalidOperationException("The circuit host is already initialized."); } try { _initialized = true; // We're ready to accept incoming JSInterop calls from here on await OnCircuitOpenedAsync(cancellationToken); await OnConnectionUpAsync(cancellationToken); // We add the root components *after* the circuit is flagged as open. // That's because AddComponentAsync waits for quiescence, which can take // arbitrarily long. In the meantime we might need to be receiving and // processing incoming JSInterop calls or similar. var count = Descriptors.Count; for (var i = 0; i < count; i++) { var(componentType, parameters, sequence) = Descriptors[i]; await Renderer.AddComponentAsync(componentType, parameters, sequence.ToString()); } Log.InitializationSucceeded(_logger); } catch (Exception ex) { // Report errors asynchronously. InitializeAsync is designed not to throw. Log.InitializationFailed(_logger, ex); UnhandledException?.Invoke(this, new UnhandledExceptionEventArgs(ex, isTerminating: false)); await TryNotifyClientErrorAsync(Client, GetClientErrorMessage(ex), ex); } })); }