public void ExportedPropertyValueDoesNotGetDisposed(IContainer container) { DisposableValue actual = container.GetExportedValue <DisposableValue>(nameof(ExportingMembersClass.PropertyReturningNewDisposableValue)); container.Dispose(); Assert.Equal(0, actual.DisposalCount); }
public void Fail_DefaultMessage() { using (DisposableValue <Mock <TraceListener> > listener = Listen()) { Report.Fail(); } }
protected override IDisposable LinkExternalInput(ITargetBlock <RestoreInfo> targetBlock) { // At a high-level, we want to combine all implicitly active configurations (ie the active config of each TFM) restore data // (via ProjectRestoreUpdate) and combine it into a single IVsProjectRestoreInfo2 instance and publish that. When a change is // made to a configuration, such as adding a PackageReference, we should react to it and push a new version of our output. If the // active configuration changes, we should react to it, and publish data from the new set of implicitly active configurations. var joinBlock = new ConfiguredProjectDataSourceJoinBlock <PackageRestoreConfiguredInput>( project => project.Services.ExportProvider.GetExportedValueOrDefault <IPackageRestoreConfiguredInputDataSource>(), JoinableFactory, _project); // Transform all restore data -> combined restore data DisposableValue <ISourceBlock <RestoreInfo> > mergeBlock = joinBlock.TransformWithNoDelta(update => update.Derive(MergeRestoreInputs)); JoinUpstreamDataSources(_activeConfigurationGroupService.ActiveConfiguredProjectGroupSource); // Set the link up so that we publish changes to target block mergeBlock.Value.LinkTo(targetBlock, DataflowOption.PropagateCompletion); return(new DisposableBag { joinBlock, // Link the active configured projects to our join block _activeConfigurationGroupService.ActiveConfiguredProjectGroupSource.SourceBlock.LinkTo(joinBlock, DataflowOption.PropagateCompletion), }); }
public void Fail() { using (DisposableValue <Mock <TraceListener> > listener = Listen()) { Report.Fail(FailureMessage); } }
protected override IDisposable LinkExternalInput(ITargetBlock <RestoreInfo> targetBlock) { // At a high-level, we want to combine all implicitly active configurations (ie the active config of each TFM) restore data // (via ProjectRestoreUpdate) and combine it into a single IVsProjectRestoreInfo2 instance and publish that. When a change is // made to a configuration, such as adding a PackageReference, we should react to it and push a new version of our output. If the // active configuration changes, we should react to it, and publish data from the new set of implicitly active configurations. var disposables = new DisposableBag(); var packageRestoreConfiguredSource = new UnwrapCollectionChainedProjectValueDataSource <IReadOnlyCollection <ConfiguredProject>, ProjectRestoreUpdate>( _project.Services, projects => projects.Select(project => GetProjectRestoreDataSource(project)), includeSourceVersions: true); disposables.AddDisposable(packageRestoreConfiguredSource); IProjectValueDataSource <IConfigurationGroup <ConfiguredProject> > activeConfiguredProjectsSource = _activeConfigurationGroupService.ActiveConfiguredProjectGroupSource; disposables.AddDisposable(activeConfiguredProjectsSource.SourceBlock.LinkTo(packageRestoreConfiguredSource, DataflowOption.PropagateCompletion)); // Transform all restore data -> combined restore data DisposableValue <ISourceBlock <RestoreInfo> > mergeBlock = packageRestoreConfiguredSource.SourceBlock .TransformWithNoDelta(update => update.Derive(MergeRestoreData)); disposables.AddDisposable(mergeBlock); // Set the link up so that we publish changes to target block mergeBlock.Value.LinkTo(targetBlock, DataflowOption.PropagateCompletion); // Join the source blocks, so if they need to switch to UI thread to complete // and someone is blocked on us on the same thread, the call proceeds JoinUpstreamDataSources(packageRestoreConfiguredSource, activeConfiguredProjectsSource); return(disposables); }
public static DisposableValue <Assembly> Load(string assemblyPath) { var context = new CollectibleAssemblyLoadContext(); var assemblyFile = new FileInfo(assemblyPath); var assembly = context.LoadFromAssemblyPath(assemblyFile.FullName); return(DisposableValue.Create(assembly, _ => context.Unload())); }
public void IfNot() { using (DisposableValue <Mock <TraceListener> > listener = Listen()) { Report.IfNot(true, FailureMessage); Report.IfNot(false, FailureMessage); } }
public void IfNot_FormatNArg() { using (DisposableValue <Mock <TraceListener> > listener = Listen()) { Report.IfNot(true, "a{0}{1}{2}e", "b", "c", "d"); Report.IfNot(false, "a{0}{1}{2}e", "b", "c", "d"); } }
public void Fail_DefaultMessage() { using (DisposableValue <Mock <TraceListener> > listener = Listen()) { listener.Value.Setup(l => l.WriteLine(DefaultFailureMessage)).Verifiable(); listener.Value.Setup(l => l.Fail(DefaultFailureMessage)).Verifiable(); Report.Fail(); } }
protected override IDisposable LinkExternalInput(ITargetBlock <IProjectVersionedValue <T> > targetBlock) { JoinUpstreamDataSources(_dataSource); DisposableValue <ISourceBlock <IProjectVersionedValue <T> > > block = _dataSource.SourceBlock.Transform(DropConfiguredProjectVersion); block.Value.LinkTo(targetBlock, DataflowOption.PropagateCompletion); return(block); }
public void IfNot_FormatNArg() { using (DisposableValue <Mock <TraceListener> > listener = Listen()) { Report.IfNot(true, "a{0}{1}{2}e", "b", "c", "d"); listener.Value.Setup(l => l.WriteLine("abcde")).Verifiable(); listener.Value.Setup(l => l.Fail("abcde")).Verifiable(); Report.IfNot(false, "a{0}{1}{2}e", "b", "c", "d"); } }
public void IfNot() { using (DisposableValue <Mock <TraceListener> > listener = Listen()) { Report.IfNot(true, FailureMessage); listener.Value.Setup(l => l.WriteLine(FailureMessage)).Verifiable(); listener.Value.Setup(l => l.Fail(FailureMessage)).Verifiable(); Report.IfNot(false, FailureMessage); } }
private static async Task OnReceived(Socket socket, DisposableValue <ArraySegment <byte> > arrSeg, CancellationToken ctsToken) { var buffer = arrSeg.Value; var buf = buffer.Array; var count = buffer.Count; if (count > 0 && buf != null) { var funcId = (DevCommandFuncId)buf[buffer.Offset]; AppLogger.Debug($"func:{funcId},{buffer.Show()}"); switch (funcId) { case DevCommandFuncId.StartStop: HandlerStartStop(socket, buffer, ctsToken); return; case DevCommandFuncId.SetSampleRate: await SetSampleRate(socket, buffer, ctsToken); return; case DevCommandFuncId.SetTrap: await SetTrap(socket, buffer, ctsToken); return; case DevCommandFuncId.SetFilter: await SetFilter(socket, buffer, ctsToken); return; case DevCommandFuncId.QueryParam: await QueryParam(socket, buffer, ctsToken); return; case DevCommandFuncId.QueryFaultState: await QueryFaultState(socket, buffer, ctsToken); return; case DevCommandFuncId.TestSingleImpedance: await TestSingleImpedance(socket, buffer, ctsToken); return; case DevCommandFuncId.TestMultiImpedance: await TestMultiImpedance(socket, buffer, ctsToken); return; } } await SimpleSend(socket, buffer); }
public void IfNotPresent() { using (DisposableValue <Mock <TraceListener> > listener = Listen()) { string?possiblyPresent = "not missing"; var missingTypeName = possiblyPresent.GetType().FullName; Report.IfNotPresent(possiblyPresent); possiblyPresent = null; Report.IfNotPresent(possiblyPresent); } }
public static IObservable <DisposableValue <ArraySegment <byte> > > ToFrameClientObservable(this Socket socket, SocketFlags socketFlags, BufferManager bufferManager, Selector selector) { return(Observable.Create <DisposableValue <ArraySegment <byte> > >(observer => { var headerState = new BufferState(new byte[sizeof(int)], 0, sizeof(int)); var contentState = new BufferState(null, 0, -1); var selectMode = socketFlags.HasFlag(SocketFlags.OutOfBand) ? SelectMode.SelectError : SelectMode.SelectRead; selector.AddCallback(selectMode, socket, _ => { try { if (headerState.Length > 0) { headerState.Advance(socket.Receive(headerState.Bytes, headerState.Offset, headerState.Length, socketFlags)); if (headerState.Length == 0) { contentState.Length = BitConverter.ToInt32(headerState.Bytes, 0); contentState.Offset = 0; contentState.Bytes = bufferManager.TakeBuffer(contentState.Length); } } if (contentState.Bytes != null) { contentState.Advance(socket.Receive(contentState.Bytes, contentState.Offset, contentState.Length, socketFlags)); if (contentState.Length == 0) { var managedBuffer = contentState.Bytes; var length = contentState.Offset; observer.OnNext(DisposableValue.Create(new ArraySegment <byte>(managedBuffer, 0, length), Disposable.Create(() => bufferManager.ReturnBuffer(managedBuffer)))); contentState.Bytes = null; headerState.Length = headerState.Offset; headerState.Offset = 0; } } } catch (Exception exception) { if (!exception.IsWouldBlock()) { observer.OnError(exception); } } }); return Disposable.Create(() => selector.RemoveCallback(SelectMode.SelectRead, socket)); })); }
protected override IDisposable?LinkExternalInput(ITargetBlock <IProjectVersionedValue <RestoreData> > targetBlock) { JoinUpstreamDataSources(_dataSource); // Take the unconfigured "restore inputs", send them to NuGet, and then return the result of that restore // We make use of TransformMany so that we can opt out of returning DisposableValue <ISourceBlock <IProjectVersionedValue <RestoreData> > > transformBlock = _dataSource.SourceBlock.TransformManyWithNoDelta(RestoreAsync); transformBlock.Value.LinkTo(targetBlock, DataflowOption.PropagateCompletion); return(transformBlock); }
public void IfNotPresent() { using (DisposableValue <Mock <TraceListener> > listener = Listen()) { string?possiblyPresent = "not missing"; string missingTypeName = possiblyPresent.GetType().FullName !; Report.IfNotPresent(possiblyPresent); listener.Value.Setup(l => l.WriteLine(It.Is <string>(v => v.Contains(missingTypeName)))).Verifiable(); listener.Value.Setup(l => l.Fail(It.Is <string>(v => v.Contains(missingTypeName)))).Verifiable(); possiblyPresent = null; Report.IfNotPresent(possiblyPresent); } }
public DisposableValue <T[]> Resize(DisposableValue <T[]> source, int size) { if (size < 0) { throw new ArgumentOutOfRangeException("size", "Must be positive."); } var dest = AllocateDisposable(size); Array.Copy(source.Value, dest.Value, size < source.Value.Length ? size : source.Value.Length); source.Dispose(); return(dest); }
public static void Main(string[] args) { var endpoint = ProgramArgs.Parse(args, new[] { "127.0.0.1:9211" }).EndPoint; var cts = new CancellationTokenSource(); var bufferManager = BufferManager.CreateBufferManager(2 << 16, 2 << 8); endpoint.ToConnectObservable() .ObserveOn(TaskPoolScheduler.Default) .Subscribe(socket => { var frameClientSubject = socket.ToFrameClientSubject(SocketFlags.None, bufferManager, cts.Token); var observerDisposable = frameClientSubject .ObserveOn(TaskPoolScheduler.Default) .Subscribe( managedBuffer => { var buf = managedBuffer.Value; if (buf.Array != null) { Console.WriteLine("Read: " + Encoding.UTF8.GetString(buf.Array, buf.Offset, buf.Count)); } managedBuffer.Dispose(); }, error => Console.WriteLine("Error: " + error.Message), () => Console.WriteLine("OnCompleted: FrameReceiver")); Console.In.ToLineObservable() .Subscribe( line => { var writeBuffer = Encoding.UTF8.GetBytes(line); frameClientSubject.OnNext(DisposableValue.Create(new ArraySegment <byte>(writeBuffer), Disposable.Empty)); }, error => Console.WriteLine("Error: " + error.Message), () => Console.WriteLine("OnCompleted: LineReader")); cts.Token.WaitHandle.WaitOne(); //Thread.Sleep(10*1000); observerDisposable.Dispose(); cts.Cancel(); }, error => Console.WriteLine("Failed to connect: " + error.Message), cts.Token); cts.Token.WaitHandle.WaitOne(); }
private static async Task <DisposableValue <ArraySegment <byte> > > ReadBody(this Stream stream, int length, BufferManager bufferManager, CancellationToken token) { if (length <= 0) { return(DisposableValue <ArraySegment <byte> > .Empty); } var buffer = bufferManager.TakeBuffer(length); if (await stream.ReadBytesCompletelyAsync(buffer, length, token) != length) { return(DisposableValue <ArraySegment <byte> > .Empty); } return(DisposableValue.Create(new ArraySegment <byte>(buffer, 0, length), Disposable.Create(() => bufferManager.ReturnBuffer(buffer)))); }
static void Main(string[] args) { var endpoint = ProgramArgs.Parse(args, new[] { "127.0.0.1:9211" }).EndPoint; var cts = new CancellationTokenSource(); var bufferManager = BufferManager.CreateBufferManager(2 << 16, 2 << 8); endpoint.ToConnectObservable() .Subscribe(client => { var frameClientSubject = client.ToFrameClientSubject(bufferManager, cts.Token); var observerDisposable = frameClientSubject .ObserveOn(TaskPoolScheduler.Default) .Subscribe( disposableBuffer => { Console.WriteLine("Read: " + Encoding.UTF8.GetString(disposableBuffer.Value.Array, 0, disposableBuffer.Value.Count)); disposableBuffer.Dispose(); }, error => Console.WriteLine("Error: " + error.Message), () => Console.WriteLine("OnCompleted: FrameReceiver")); Console.In.ToLineObservable() .Subscribe( line => { var writeBuffer = Encoding.UTF8.GetBytes(line); frameClientSubject.OnNext(DisposableValue.Create(new ArraySegment <byte>(writeBuffer), Disposable.Empty)); }, error => Console.WriteLine("Error: " + error.Message), () => Console.WriteLine("OnCompleted: LineReader")); observerDisposable.Dispose(); cts.Cancel(); }, error => { Console.WriteLine("Failed to connect: " + error.Message); Environment.Exit(-1); }); cts.Token.WaitHandle.WaitOne(); }
static void Main(string[] args) { var endpoint = ProgramArgs.Parse(args, new[] { "127.0.0.1:9211" }).EndPoint; var cts = new CancellationTokenSource(); var bufferManager = BufferManager.CreateBufferManager(2 << 16, 2 << 8); var selector = new Selector(); Task.Factory.StartNew(() => selector.Dispatch(60000000, cts.Token), cts.Token); endpoint.ToConnectObservable(selector, cts.Token) .Subscribe(socket => { var frameClientSubject = socket.ToFrameClientSubject(SocketFlags.None, bufferManager, selector, cts.Token); var observerDisposable = frameClientSubject .ObserveOn(TaskPoolScheduler.Default) .Subscribe( disposableBuffer => { Console.WriteLine("Read: " + Encoding.UTF8.GetString(disposableBuffer.Value.Array, 0, disposableBuffer.Value.Count)); disposableBuffer.Dispose(); }, error => Console.WriteLine("Error: " + error.Message), () => Console.WriteLine("OnCompleted: FrameReceiver")); Console.In.ToLineObservable() .Subscribe( line => { var writeBuffer = Encoding.UTF8.GetBytes(line); frameClientSubject.OnNext(DisposableValue.Create(new ArraySegment <byte>(writeBuffer, 0, writeBuffer.Length), Disposable.Empty)); }, error => Console.WriteLine("Error: " + error.Message), () => Console.WriteLine("OnCompleted: LineReader")); observerDisposable.Dispose(); cts.Cancel(); }); cts.Token.WaitHandle.WaitOne(); }
protected override IDisposable LinkExternalInput(ITargetBlock <RestoreUpdate> targetBlock) { IProjectValueDataSource <IProjectSubscriptionUpdate> source = _projectSubscriptionService.JointRuleSource; // Transform the changes from evaluation/design-time build -> restore data DisposableValue <ISourceBlock <RestoreUpdate> > transformBlock = source.SourceBlock.TransformWithNoDelta(update => update.Derive(u => CreateRestoreInput(u.ProjectConfiguration, u.CurrentState)), suppressVersionOnlyUpdates: false, // We need to coordinate these at the unconfigured-level ruleNames: s_rules); // Set the link up so that we publish changes to target block transformBlock.Value.LinkTo(targetBlock, DataflowOption.PropagateCompletion); // Join the source blocks, so if they need to switch to UI thread to complete // and someone is blocked on us on the same thread, the call proceeds JoinUpstreamDataSources(source); return(transformBlock); }
/// <summary> /// Starts the worker process, and returns a disposable pipe connection. Disposing the connection will also destroy the worker process. /// </summary> /// <returns>A pipe connection to the worker process.</returns> public async Task <DisposableValue <PipeServer> > ExecuteAsync() { myWorkerProcess = StartWorkerProcess(); myPipeServer = await StartPipeServerAsync(); if (myConfig.IsDebug) { Console.WriteLine("Waiting for debugger to attach to child process. Press enter to continue."); Console.ReadLine(); } return(DisposableValue.Create(myPipeServer, pipeServer => { StopWorkerProcess(); myPipeServer?.Dispose(); myWorkerProcess?.Dispose(); })); }
protected override IDisposable?LinkExternalInput(ITargetBlock <EnumCollectionProjectValue> targetBlock) { IProjectValueDataSource <IProjectSubscriptionUpdate> source = SubscriptionService.ProjectRuleSource; // Transform the values from evaluation to structure from the rule schema. DisposableValue <ISourceBlock <EnumCollectionProjectValue> > transformBlock = source.SourceBlock.TransformWithNoDelta( update => update.Derive(Transform), suppressVersionOnlyUpdates: false, ruleNames: RuleNames); // Set the link up so that we publish changes to target block. transformBlock.Value.LinkTo(targetBlock, DataflowOption.PropagateCompletion); // Join the source blocks, so if they need to switch to UI thread to complete // and someone is blocked on us on the same thread, the call proceeds. JoinUpstreamDataSources(source); return(transformBlock); }
protected override IDisposable LinkExternalInput(ITargetBlock <RestoreInfo> targetBlock) { // At a high-level, we want to combine all implicitly active configurations (ie the active config of each TFM) restore data // (via ProjectRestoreUpdate) and combine it into a single IVsProjectRestoreInfo2 instance and publish that. When a change is // made to a configuration, such as adding a PackageReference, we should react to it and push a new version of our output. If the // active configuration changes, we should react to it, and publish data from the new set of implicitly active configurations. var disposables = new DisposableBag(); var restoreConfiguredInputSource = new UnwrapCollectionChainedProjectValueDataSource <IReadOnlyCollection <ConfiguredProject>, PackageRestoreConfiguredInput>( _project, projects => projects.Select(project => project.Services.ExportProvider.GetExportedValueOrDefault <IPackageRestoreConfiguredInputDataSource>()) .WhereNotNull() // Filter out those without PackageReference .Select(DropConfiguredProjectVersions), includeSourceVersions: true); disposables.Add(restoreConfiguredInputSource); IProjectValueDataSource <IConfigurationGroup <ConfiguredProject> > activeConfiguredProjectsSource = _activeConfigurationGroupService.ActiveConfiguredProjectGroupSource; disposables.Add(activeConfiguredProjectsSource.SourceBlock.LinkTo(restoreConfiguredInputSource, DataflowOption.PropagateCompletion)); // Dataflow from two configurations can depend on a same unconfigured level data source, and processes it at a different speed. // Introduce a forward-only block to prevent regressions in versions. var forwardOnlyBlock = ProjectDataSources.CreateDataSourceVersionForwardOnlyFilteringBlock <IReadOnlyCollection <PackageRestoreConfiguredInput> >(); disposables.Add(restoreConfiguredInputSource.SourceBlock.LinkTo(forwardOnlyBlock, DataflowOption.PropagateCompletion)); // Transform all restore data -> combined restore data DisposableValue <ISourceBlock <RestoreInfo> > mergeBlock = forwardOnlyBlock.TransformWithNoDelta(update => update.Derive(MergeRestoreInputs)); disposables.Add(mergeBlock); // Set the link up so that we publish changes to target block mergeBlock.Value.LinkTo(targetBlock, DataflowOption.PropagateCompletion); // Join the source blocks, so if they need to switch to UI thread to complete // and someone is blocked on us on the same thread, the call proceeds JoinUpstreamDataSources(restoreConfiguredInputSource, activeConfiguredProjectsSource); _packageReferenceTelemetryService.PostPackageRestoreEvent(PackageRestoreOperationNames.PackageRestoreUnconfiguredInputDataSourceLinkedToExternalInput); return(disposables); }
public static void Example_Dispose() { var d = new DisposableValue(); Console.WriteLine("Passing value variable:"); CallDispose(d); CallDispose(d); CallDispose(d); IDisposable i = d; Console.WriteLine("Passing interface variable:"); CallDispose(i); CallDispose(i); CallDispose(i); Console.WriteLine("Call Dispose on value variable:"); d.Dispose(); d.Dispose(); d.Dispose(); }
protected override IDisposable LinkExternalInput(ITargetBlock <IProjectVersionedValue <UpToDateCheckConfiguredInput> > targetBlock) { // Provides the set of implicitly active configured projects IProjectValueDataSource <IConfigurationGroup <ConfiguredProject> > activeConfiguredProjectsSource = _activeConfigurationGroupService.ActiveConfiguredProjectGroupSource; // Aggregates implicitly active UpToDateCheckImplicitConfiguredInput inputs from their sources var restoreConfiguredInputSource = new UnwrapCollectionChainedProjectValueDataSource <IReadOnlyCollection <ConfiguredProject>, UpToDateCheckImplicitConfiguredInput>( _configuredProject, projects => projects.Select(project => project.Services.ExportProvider.GetExportedValueOrDefault <IUpToDateCheckImplicitConfiguredInputDataSource>()) .WhereNotNull() // Filter out any configurations which don't have this export .Select(DropConfiguredProjectVersions), includeSourceVersions: true); // Dataflow from two configurations can depend on a same unconfigured level data source, and processes it at a different speed. // Introduce a forward-only block to prevent regressions in versions. var forwardOnlyBlock = ProjectDataSources.CreateDataSourceVersionForwardOnlyFilteringBlock <IReadOnlyCollection <UpToDateCheckImplicitConfiguredInput> >(); DisposableValue <ISourceBlock <IProjectVersionedValue <UpToDateCheckConfiguredInput> > > mergeBlock = forwardOnlyBlock.TransformWithNoDelta(update => update.Derive(MergeInputs)); JoinUpstreamDataSources(restoreConfiguredInputSource, activeConfiguredProjectsSource); return(new DisposableBag { restoreConfiguredInputSource, activeConfiguredProjectsSource.SourceBlock.LinkTo(restoreConfiguredInputSource, DataflowOption.PropagateCompletion), restoreConfiguredInputSource.SourceBlock.LinkTo(forwardOnlyBlock, DataflowOption.PropagateCompletion), mergeBlock, mergeBlock.Value.LinkTo(targetBlock, DataflowOption.PropagateCompletion) }); IProjectValueDataSource <UpToDateCheckImplicitConfiguredInput> DropConfiguredProjectVersions(IUpToDateCheckImplicitConfiguredInputDataSource dataSource) { // Wrap it in a data source that will drop project version and identity versions so as they will never agree // on these versions as they are unique to each configuration. They'll be consistent by all other versions. return(new DropConfiguredProjectVersionDataSource <UpToDateCheckImplicitConfiguredInput>(_configuredProject.UnconfiguredProject, dataSource)); }
protected override IDisposable LinkExternalInput(ITargetBlock <IProjectVersionedValue <UpToDateCheckConfiguredInput> > targetBlock) { // Aggregates implicitly active UpToDateCheckImplicitConfiguredInput inputs from their sources var joinBlock = new ConfiguredProjectDataSourceJoinBlock <UpToDateCheckImplicitConfiguredInput>( project => project.Services.ExportProvider.GetExportedValueOrDefault <IUpToDateCheckImplicitConfiguredInputDataSource>(), JoinableFactory, _configuredProject.UnconfiguredProject); // Merges UpToDateCheckImplicitConfiguredInputs into a UpToDateCheckConfiguredInput DisposableValue <ISourceBlock <IProjectVersionedValue <UpToDateCheckConfiguredInput> > > mergeBlock = joinBlock.TransformWithNoDelta(update => update.Derive(MergeInputs)); JoinUpstreamDataSources(_activeConfigurationGroupService.ActiveConfiguredProjectGroupSource); // Set the link up so that we publish changes to target block mergeBlock.Value.LinkTo(targetBlock, DataflowOption.PropagateCompletion); return(new DisposableBag { joinBlock, // Link the active configured projects to our join block _activeConfigurationGroupService.ActiveConfiguredProjectGroupSource.SourceBlock.LinkTo(joinBlock, DataflowOption.PropagateCompletion), });
protected override IDisposable?LinkExternalInput(ITargetBlock <IProjectVersionedValue <ISet <WorkloadDescriptor> > > targetBlock) { IProjectValueDataSource <IProjectSubscriptionUpdate> source = _projectSubscriptionService.ProjectBuildRuleSource; // Transform the changes from design-time build -> workload data DisposableValue <ISourceBlock <IProjectVersionedValue <ISet <WorkloadDescriptor> > > > transformBlock = source.SourceBlock.TransformWithNoDelta(update => update.Derive(u => CreateWorkloadDescriptor(u.CurrentState)), suppressVersionOnlyUpdates: false, ruleNames: s_rules); // Set the link up so that we publish changes to target block transformBlock.Value.LinkTo(targetBlock, DataflowOption.PropagateCompletion); // Join the source blocks, so if they need to switch to UI thread to complete // and someone is blocked on us on the same thread, the call proceeds JoinUpstreamDataSources(source); return(transformBlock); }