Ejemplo n.º 1
0
        public UriPropagatorBlock(
            CancellationToken cancellationToken,
            ILogger logger,
            StrategyEvents events,
            Func <Uri, bool> shouldAccept,
            Action emitHeartbeat,
            TaskScheduler scheduler)
        {
            _cancellationToken = cancellationToken;
            _logger            = logger;
            _events            = events;
            _shouldAccept      = shouldAccept;
            _emitHeartbeat     = emitHeartbeat;

            var buffer = new BufferBlock <Uri>(
                new ExecutionDataflowBlockOptions
            {
                MaxDegreeOfParallelism = 1,     // TODO: add config setting
                CancellationToken      = cancellationToken,
                EnsureOrdered          = false,
                TaskScheduler          = scheduler
            });

            _target = buffer;
            _source = buffer;
        }
Ejemplo n.º 2
0
        protected override void Initialize()
        {
            // Create our broadcast block for subscribers to get new ILaunchProfiles Information
            _broadcastBlock     = DataflowBlockSlim.CreateBroadcastBlock <ILaunchSettings>();
            _changedSourceBlock = _broadcastBlock.SafePublicize();


            // Subscribe to changes to the broadcast block using the idle scheduler. This should filter out a lot of the intermediates
            // states that files can be in.
            if (_projectSubscriptionService != null)
            {
                // The use of AsyncLazy with dataflow can allow state stored in the execution context to leak through. The downstream affect is
                // calls to say, get properties, may fail. To avoid this, we capture the execution context here, and it will be reapplied when
                // we get new subscription data from the dataflow.
                ITargetBlock <IProjectVersionedValue <Tuple <IProjectSubscriptionUpdate, IProjectCapabilitiesSnapshot> > > projectChangesBlock = DataflowBlockSlim.CreateActionBlock(
                    DataflowUtilities.CaptureAndApplyExecutionContext <IProjectVersionedValue <Tuple <IProjectSubscriptionUpdate, IProjectCapabilitiesSnapshot> > >(ProjectRuleBlock_ChangedAsync));
                StandardRuleDataflowLinkOptions evaluationLinkOptions = DataflowOption.WithRuleNames(ProjectDebugger.SchemaName);

                _projectRuleSubscriptionLink = ProjectDataSources.SyncLinkTo(
                    _projectSubscriptionService.ProjectRuleSource.SourceBlock.SyncLinkOptions(evaluationLinkOptions),
                    _commonProjectServices.Project.Capabilities.SourceBlock.SyncLinkOptions(),
                    projectChangesBlock,
                    linkOptions: DataflowOption.PropagateCompletion);
            }

            // Make sure we are watching the file at this point
            WatchLaunchSettingsFile();
        }
Ejemplo n.º 3
0
        public StageProcess()
        {
            var queue  = new Queue <T>();
            var source = new BufferBlock <T[]>();

            var target = new ActionBlock <T>(item =>
            {
                queue.Enqueue(item);
                if (queue.Count > WS)
                {
                    queue.Dequeue();
                }

                if (queue.Count == WS)
                {
                    source.Post(queue.ToArray());
                }
            });

            target.Completion.ContinueWith(delegate
            {
                if (queue.Count > 0 && queue.Count < WS)
                {
                    source.Post(queue.ToArray());
                }

                source.Complete();
            });

            _target = target;
            _source = source;
        }
Ejemplo n.º 4
0
        protected override void Initialize()
        {
            var debugProfilesBlock = new TransformBlock <ILaunchSettings, IProjectVersionedValue <IReadOnlyList <IEnumValue> > >(
                update =>
            {
                // Compute the new enum values from the profile provider
                var generatedResult = DebugProfileEnumValuesGenerator.GetEnumeratorEnumValues(update).ToImmutableList();
                _dataSourceVersion++;
                var dataSources = ImmutableDictionary <NamedIdentity, IComparable> .Empty.Add(DataSourceKey, DataSourceVersion);
                return(new ProjectVersionedValue <IReadOnlyList <IEnumValue> >(generatedResult, dataSources));
            });

            var broadcastBlock = new BroadcastBlock <IProjectVersionedValue <IReadOnlyList <IEnumValue> > >(b => b);

            _launchProfileProviderLink = LaunchSettingProvider.SourceBlock.LinkTo(
                debugProfilesBlock,
                linkOptions: new DataflowLinkOptions {
                PropagateCompletion = true
            });

            _debugProviderLink = debugProfilesBlock.LinkTo(broadcastBlock, new DataflowLinkOptions {
                PropagateCompletion = true
            });

            _publicBlock = broadcastBlock.SafePublicize();
        }
Ejemplo n.º 5
0
        /// <summary>
        /// The default Constructor.
        /// </summary>
        /// <param name="incoming">Источник входящих NMS-сообщений.</param>
        /// <param name="outgoing">Канал для исходящих NMS-сообщений.</param>
        internal NmsProtocol(IReceivableSourceBlock <NmsMessage> incoming, ITargetBlock <NmsMessage> outgoing)
        {
            IsDisposed      = false;
            _cts            = new CancellationTokenSource();
            _defaultOptions = new NibusOptions {
                Token = _cts.Token
            };

            IncomingMessages = incoming;
            OutgoingMessages = outgoing;

            if (SynchronizationContext.Current == null)
            {
                SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
            }

            var ui           = TaskScheduler.FromCurrentSynchronizationContext();
            var infoHandlers = new ActionBlock <NmsMessage>(
                message => OnInformationReport((NmsInformationReport)message),
                new ExecutionDataflowBlockOptions
            {
                //CancellationToken = _cts.Token,
                TaskScheduler = ui
            });

            IncomingMessages.LinkTo(
                infoHandlers,
                message => message.ServiceType == NmsServiceType.InformationReport);
        }
Ejemplo n.º 6
0
        protected override void Initialize()
        {
            base.Initialize();

            // Create an action block to process the design time inputs and configuration general changes
            ITargetBlock <IProjectVersionedValue <ValueTuple <DesignTimeInputs, IProjectSubscriptionUpdate> > > inputsAction = DataflowBlockSlim.CreateActionBlock <IProjectVersionedValue <ValueTuple <DesignTimeInputs, IProjectSubscriptionUpdate> > >(ProcessDataflowChanges);

            _broadcastBlock = DataflowBlockSlim.CreateBroadcastBlock <IProjectVersionedValue <DesignTimeInputsDelta> >(nameFormat: nameof(DesignTimeInputsChangeTracker) + "Broadcast {1}");
            _publicBlock    = AllowSourceBlockCompletion ? _broadcastBlock : _broadcastBlock.SafePublicize();

            Assumes.Present(_project.Services.ProjectAsynchronousTasks);

            IDisposable projectLink = ProjectDataSources.SyncLinkTo(
                _inputsDataSource.SourceBlock.SyncLinkOptions(
                    linkOptions: DataflowOption.PropagateCompletion),
                _projectSubscriptionService.ProjectRuleSource.SourceBlock.SyncLinkOptions(
                    linkOptions: DataflowOption.WithRuleNames(ConfigurationGeneral.SchemaName)),
                inputsAction,
                DataflowOption.PropagateCompletion,
                cancellationToken: _project.Services.ProjectAsynchronousTasks.UnloadCancellationToken);

            // Create an action block to process file change notifications
            ITargetBlock <IProjectVersionedValue <string[]> > fileWatcherAction = DataflowBlockSlim.CreateActionBlock <IProjectVersionedValue <string[]> >(ProcessFileChangeNotification);
            IDisposable watcherLink = _fileWatcher.SourceBlock.LinkTo(fileWatcherAction, DataflowOption.PropagateCompletion);

            _disposables.Add(projectLink);
            _disposables.Add(watcherLink);

            JoinUpstreamDataSources(_inputsDataSource, _projectSubscriptionService.ProjectRuleSource, _fileWatcher);
        }
Ejemplo n.º 7
0
        public static async Task <List <T> > ToListAsync <T>(this IReceivableSourceBlock <T> source,
                                                             CancellationToken cancellationToken = default)
        {
            if (source is null)
            {
                throw new NullReferenceException();
            }
            Contract.EndContractBlock();

            var result = new List <T>();

            do
            {
                while (!cancellationToken.IsCancellationRequested &&
                       source.TryReceive(null, out var e))
                {
                    result.Add(e);
                }
            }while (!cancellationToken.IsCancellationRequested &&
                    await source.OutputAvailableAsync(cancellationToken));

            cancellationToken.ThrowIfCancellationRequested();

            return(result);
        }
 public PaymentProcessor(IReceivableSourceBlock <Order> source, TextWriter writer, Func <PaymentProcessor, Action <Order> > completionFactory = null, int delay = 2000)
 {
     this.writer       = writer;
     this.delay        = delay;
     this.source       = source;
     this.onCompletion = completionFactory != null?completionFactory(this) : (o => { });
 }
Ejemplo n.º 9
0
        internal static bool TestTryReceiveAll <T>(IReceivableSourceBlock <T> source, int msgsCount)
        {
            IList <T> items;

            if (!source.TryReceiveAll(out items))
            {
                return(false);
            }

            if (source is WriteOnceBlock <T> || source is BroadcastBlock <T> ) // They only propagate one msg at a time
            {
                msgsCount = 1;
            }

            if (items.Count != msgsCount)
            {
                Console.WriteLine("* TryReceiveAll failed! Returned items count {0} and expected {1}", items.Count, msgsCount);
                return(false);
            }

            bool expectedResult = false;

            if (source is WriteOnceBlock <T> || source is BroadcastBlock <T> ) // because WriteOnce and Broadcast always pass a copy and keep the msg, so TryReceive should succeed
            {
                expectedResult = true;
            }

            if (source.TryReceiveAll(out items) != expectedResult)
            {
                Console.WriteLine(" TryReceiveAll failed! Returned {0} and expected to return {1}", expectedResult, !expectedResult);
                return(false);
            }

            return(true);
        }
Ejemplo n.º 10
0
        public MsBuildFileSystemWatcher(string directory, string filter, int delayMilliseconds, int recoveryDelayMilliseconds, IFileSystem fileSystem, IMsBuildFileSystemFilter fileSystemFilter, IActionLog log, TaskScheduler taskScheduler = null)
        {
            Requires.NotNullOrWhiteSpace(directory, nameof(directory));
            Requires.NotNullOrWhiteSpace(filter, nameof(filter));
            Requires.Range(delayMilliseconds >= 0, nameof(delayMilliseconds));
            Requires.Range(recoveryDelayMilliseconds >= 0, nameof(recoveryDelayMilliseconds));
            Requires.NotNull(fileSystem, nameof(fileSystem));
            Requires.NotNull(fileSystemFilter, nameof(fileSystemFilter));

            _directory                 = directory;
            _filter                    = filter;
            _delayMilliseconds         = delayMilliseconds;
            _recoveryDelayMilliseconds = recoveryDelayMilliseconds;
            _fileSystem                = fileSystem;
            _fileSystemFilter          = fileSystemFilter;
            _taskScheduler             = taskScheduler ?? TaskScheduler.Default;
            _log = log;

            _entries        = new MsBuildFileSystemWatcherEntries();
            _queue          = new ConcurrentQueue <IFileSystemChange>();
            _broadcastBlock = new BroadcastBlock <Changeset>(b => b, new DataflowBlockOptions {
                TaskScheduler = _taskScheduler
            });
            SourceBlock = _broadcastBlock.SafePublicize();
            _fileSystemFilter.Seal();
        }
Ejemplo n.º 11
0
        protected override async Task InitializeCoreAsync(CancellationToken cancellationToken)
        {
            await base.InitializeCoreAsync(cancellationToken);

            _broadcastBlock = DataflowBlockSlim.CreateBroadcastBlock <IProjectVersionedValue <RestoreData> >();
            _publicBlock    = _broadcastBlock.SafePublicize();
        }
Ejemplo n.º 12
0
        public FrameQueueBlock(DataflowBlockOptions broadcastBlockOptions, ExecutionDataflowBlockOptions bufferBlockOptions)
        {
            // The source part of the propagator holds arrays of size windowSize
            // and propagates data out to any connected targets.
            _source = new BroadcastBlock <T>(f => f, broadcastBlockOptions);

            // The target part receives data and adds them to the queue.
            _target = new BufferBlock <T>(bufferBlockOptions);

            //	(item =>
            //{
            //	// Add the item to the queue.
            //	frameQueue.Enqueue(item);
            //}, actionBlockOptions);

            // When the target is set to the completed state, propagate out any
            // remaining data and set the source to the completed state.
            _target.Completion.ContinueWith(delegate
            {
                _source.Complete();
            });

            _mtarget = _target;
            _msource = _source;

            //estimated fps
            //Based on 24 fps, (1sec/24 frames = ~42 ms)
            _tim = new Timer(42, DisplayFrame, false);
            _tim.Start();
        }
Ejemplo n.º 13
0
        /// <summary>
        /// The DebugProfileProvider sinks 2 sets of information
        /// 1, Changes to the launchsettings.json file on disk
        /// 2. Changes to the ActiveDebugProfile property in the .user file
        /// </summary>
        protected override void Initialize()
        {
            // Create our broadcast block for subscribers to get new ILaunchProfiles Information
            _broadcastBlock     = new BroadcastBlock <ILaunchSettings>(s => s);
            _changedSourceBlock = _broadcastBlock.SafePublicize();


            // Subscribe to changes to the broadcast block using the idle scheduler. This should filter out a lot of the intermediates
            // states that files can be in.
            if (ProjectSubscriptionService != null)
            {
                // The use of AsyncLazy with dataflow can allow state stored in the execution context to leak through. The downstream affect is
                // calls to say, get properties, may fail. To avoid this, we capture the execution context here, and it will be reapplied when
                // we get new subscription data from the dataflow.
                var projectChangesBlock = new ActionBlock <IProjectVersionedValue <IProjectSubscriptionUpdate> >(
                    DataflowUtilities.CaptureAndApplyExecutionContext <IProjectVersionedValue <IProjectSubscriptionUpdate> >(ProjectRuleBlock_ChangedAsync));

                ProjectRuleSubscriptionLink = ProjectSubscriptionService.ProjectRuleSource.SourceBlock.LinkTo(
                    projectChangesBlock,
                    ruleNames: ProjectDebugger.SchemaName,
                    linkOptions: new DataflowLinkOptions {
                    PropagateCompletion = true
                });
            }

            // Make sure we are watching the file at this point
            WatchLaunchSettingsFile();
        }
Ejemplo n.º 14
0
        public async Task <Int64> ConsumeMultiAsync(IReceivableSourceBlock <Model[]> source)
        {
            // Initialize a counter to track the number of bytes that are processed.
            Int64 recordsProcessed = 0;

            // Read from the source buffer until the source buffer has no
            // available output data.
            while (await source.OutputAvailableAsync())
            {
                Model[] data;
                while (source.TryReceive(out data))
                {
                    foreach (var item in data)
                    {
                        dataCollection.Add(item);
                    }

                    var duplicates = dataCollection.GroupBy(d => d.GetType()
                                                            .GetProperties()
                                                            .Where(p => p.Name == key)
                                                            .First()
                                                            .GetValue(d))
                                     .SelectMany(g => g.Skip(1));

                    var items = duplicates.Except(ValidationResult);
                    foreach (var item in items)
                    {
                        ValidationResult.Add(item);
                    }
                    recordsProcessed += data.Length;
                }
            }

            return(recordsProcessed);
        }
        protected override void Initialize()
        {
            IPropagatorBlock <IProjectVersionedValue <ILaunchSettings>, IProjectVersionedValue <IReadOnlyList <IEnumValue> > > debugProfilesBlock = DataflowBlockSlim.CreateTransformBlock <IProjectVersionedValue <ILaunchSettings>, IProjectVersionedValue <IReadOnlyList <IEnumValue> > >(
                update =>
            {
                // Compute the new enum values from the profile provider
                var generatedResult = DebugProfileEnumValuesGenerator.GetEnumeratorEnumValues(update.Value).ToImmutableList();
                _dataSourceVersion++;
                ImmutableDictionary <NamedIdentity, IComparable> dataSources = ImmutableDictionary <NamedIdentity, IComparable> .Empty.Add(DataSourceKey, DataSourceVersion);
                return(new ProjectVersionedValue <IReadOnlyList <IEnumValue> >(generatedResult, dataSources));
            });

            IBroadcastBlock <IProjectVersionedValue <IReadOnlyList <IEnumValue> > > broadcastBlock = DataflowBlockSlim.CreateBroadcastBlock <IProjectVersionedValue <IReadOnlyList <IEnumValue> > >();

            // The interface has two definitions of SourceBlock: one from
            // ILaunchSettingsProvider, and one from IProjectValueDataSource<T> (via
            // IVersionedLaunchSettingsProvider). We need the cast to pick the proper one.
            _launchProfileProviderLink = ((IProjectValueDataSource <ILaunchSettings>)LaunchSettingProvider).SourceBlock.LinkTo(
                debugProfilesBlock,
                linkOptions: DataflowOption.PropagateCompletion);

            JoinUpstreamDataSources(LaunchSettingProvider);

            _debugProviderLink = debugProfilesBlock.LinkTo(broadcastBlock, DataflowOption.PropagateCompletion);

            _publicBlock = broadcastBlock.SafePublicize();
        }
Ejemplo n.º 16
0
        internal static bool TestTryReceive <T>(IReceivableSourceBlock <T> source, int msgsCount)
        {
            T item;

            for (int i = 0; i < msgsCount; i++)
            {
                if (!source.TryReceive(out item))
                {
                    Console.WriteLine(" TryReceive failed! Returned false and expected to return true (i={0})", i);
                    return(false);
                }
            }

            bool expectedResult = false;

            if (source is WriteOnceBlock <T> || source is BroadcastBlock <T> ) // because WriteOnce and Broadcast always pass a copy and keep the msg, so TryReceive should succeed
            {
                expectedResult = true;
            }

            if (source.TryReceive(out item) != expectedResult)
            {
                Console.WriteLine(" TryReceive failed! Returned {0} and expected to return {1}", expectedResult, !expectedResult);
                return(false);
            }

            return(true);
        }
Ejemplo n.º 17
0
 private static async Task ConsumeAsync(IReceivableSourceBlock<LogObject> source, CancellationToken cancellationToken)
 {
     while (await source.OutputAvailableAsync(cancellationToken))
     {
         var log = await source.ReceiveAsync();
         // do some stuff
     }
 }
Ejemplo n.º 18
0
 public ReceivablePropagatorDataflowWrapper(ITargetBlock <TInput> originalTargetBlock
                                            , IDataflowBlock currentSourceBlock
                                            , ISourceBlock <TOutput> finalSourceBlock
                                            , bool?propagateCompletion = null)
     : base(originalTargetBlock, currentSourceBlock, finalSourceBlock, propagateCompletion)
 {
     _receivableSourceBlock = finalSourceBlock as IReceivableSourceBlock <TOutput>;
 }
        /// <summary>Creates an <see cref="IAsyncEnumerable{TOutput}"/> that enables receiving all of the data from the source.</summary>
        /// <typeparam name="TOutput">Specifies the type of data contained in the source.</typeparam>
        /// <param name="source">The source from which to asynchronously receive.</param>
        /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> which may be used to cancel the receive operation.</param>
        /// <returns>The created async enumerable.</returns>
        /// <exception cref="System.ArgumentNullException">The <paramref name="source"/> is null (Nothing in Visual Basic).</exception>
        public static IAsyncEnumerable <TOutput> ReceiveAllAsync <TOutput>(this IReceivableSourceBlock <TOutput> source, CancellationToken cancellationToken = default)
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(ReceiveAllAsyncCore(source, cancellationToken));
Ejemplo n.º 20
0
 public IDisposable LinkTo(
     IReceivableSourceBlock <IProjectVersionedValue <IProjectSubscriptionUpdate> > sourceBlock,
     ITargetBlock <IProjectVersionedValue <IProjectSubscriptionUpdate> > target,
     IEnumerable <string> ruleNames,
     bool suppressVersionOnlyUpdates)
 {
     return(_wrapper.LinkTo(sourceBlock, target, ruleNames, suppressVersionOnlyUpdates));
 }
Ejemplo n.º 21
0
		public static bool TryReceive<TOutput> (this IReceivableSourceBlock<TOutput> source, out TOutput item)
		{
			item = default (TOutput);
			if (source == null)
				throw new ArgumentNullException ("source");

			return source.TryReceive (null, out item);
		}
Ejemplo n.º 22
0
        /// <summary>
        /// The default Constructor.
        /// </summary>
        /// <param name="transform">Функция трансформации.</param>
        public BroadcastTransformBlock(Func <TInput, TOutput> transform)
        {
            var source = new BroadcastBlock <TOutput>(m => m);
            var target = new ActionBlock <TInput>(m => source.Post(transform(m)));

            target.Completion.ContinueWith(delegate { source.Complete(); });
            _target = target;
            _source = source;
        }
 static async IAsyncEnumerable <TOutput> ReceiveAllAsyncCore(IReceivableSourceBlock <TOutput> source, [EnumeratorCancellation] CancellationToken cancellationToken)
 {
     while (await source.OutputAvailableAsync(cancellationToken).ConfigureAwait(false))
     {
         while (source.TryReceive(out TOutput? item))
         {
             yield return(item);
         }
     }
 }
Ejemplo n.º 24
0
 internal static async Task Consume(IReceivableSourceBlock <SearchResultEntry> queue)
 {
     while (await queue.OutputAvailableAsync())
     {
         SearchResultEntry entry;
         while (queue.TryReceive(out entry))
         {
         }
     }
 }
 public PropagatorHookBase(string name,
                           IDataflowBlock block,
                           ITargetBlock <TInput> target,
                           ISourceBlock <TOutput> source)
 {
     Name             = name;
     Block            = block;
     Target           = target;
     Source           = source;
     SourceReceivable = source as IReceivableSourceBlock <TOutput>;
 }
Ejemplo n.º 26
0
        public static IList <T> ReceiveAll <T>(this IReceivableSourceBlock <T> buffer)
        {
            IList <T> receivedItems = new List <T>();
            T         receivedItem  = default(T);

            while (buffer.TryReceive(out receivedItem))
            {
                receivedItems.Add(receivedItem);
            }
            return(receivedItems);
        }
Ejemplo n.º 27
0
 public async void AgentInit(IReceivableSourceBlock <ScheduledTaskQueueDto> buffer)
 {
     while (await buffer.OutputAvailableAsync())
     {
         ScheduledTaskQueueDto task;
         while (buffer.TryReceive(out task))
         {
             ProcessTask(task);
         }
     }
 }
Ejemplo n.º 28
0
 public static async Task <T?> ReceiveAsyncIfEver <T>(this IReceivableSourceBlock <T> source)
     where T : struct
 {
     try
     {
         return(await source.ReceiveAsync());
     }
     catch (InvalidOperationException)
     {
         return(null);
     }
 }
        protected override void Initialize()
        {
            base.Initialize();

            _broadcastBlock = DataflowBlockSlim.CreateBroadcastBlock <IProjectVersionedValue <string[]> >(nameFormat: nameof(DesignTimeInputsFileWatcher) + "Broadcast {1}");
            _publicBlock    = AllowSourceBlockCompletion ? _broadcastBlock : _broadcastBlock.SafePublicize();

            _actionBlock = DataflowBlockFactory.CreateActionBlock <IProjectVersionedValue <DesignTimeInputs> >(ProcessDesignTimeInputs, _project);

            _dataSourceLink = _designTimeInputsDataSource.SourceBlock.LinkTo(_actionBlock, DataflowOption.PropagateCompletion);

            JoinUpstreamDataSources(_designTimeInputsDataSource);
        }
Ejemplo n.º 30
0
    // <snippet2>
    static async Task <int> ConsumeAsync(IReceivableSourceBlock <byte[]> source)
    {
        int bytesProcessed = 0;

        while (await source.OutputAvailableAsync())
        {
            while (source.TryReceive(out byte[] data))
            {
                bytesProcessed += data.Length;
            }
        }
        return(bytesProcessed);
    }
        public MsBuildFileSystemWatcher(string directory, string filter, int delayMilliseconds, IFileSystem fileSystem, IMsBuildFileSystemFilter fileSystemFilter, TaskScheduler taskScheduler = null, IActionLog log = null) {
            Requires.NotNullOrWhiteSpace(directory, nameof(directory));
            Requires.NotNullOrWhiteSpace(filter, nameof(filter));
            Requires.Range(delayMilliseconds >= 0, nameof(delayMilliseconds));
            Requires.NotNull(fileSystem, nameof(fileSystem));
            Requires.NotNull(fileSystemFilter, nameof(fileSystemFilter));

            _directory = directory;
            _filter = filter;
            _delayMilliseconds = delayMilliseconds;
            _fileSystem = fileSystem;
            _fileSystemFilter = fileSystemFilter;
            _taskScheduler = taskScheduler ?? TaskScheduler.Default;
            _log = log ?? ProjectSystemActionLog.Default;

            _queue = new ConcurrentQueue<IFileSystemChange>();
            _broadcastBlock = new BroadcastBlock<Changeset>(b => b, new DataflowBlockOptions { TaskScheduler = _taskScheduler });
            SourceBlock = _broadcastBlock.SafePublicize();
            _fileSystemFilter.Seal();
        }