/// <summary> /// Creates a new instance configured to output to the given writer. /// </summary> /// <param name="eventSource"> /// The event source to listen to. /// </param> /// <param name="writer">The TextWriter where to send the output. Note that the writer will be disposed when the TextWriterEventListener is itself disposed.</param> /// <param name="baseTime"> /// The UTC time representing time 0 for this listener. /// </param> /// <param name="warningMapper"> /// An optional delegate that is used to map warnings into errors or to suppress warnings. /// </param> /// <param name="level"> /// The base level of data to be sent to the listener. /// </param> /// <param name="timeDisplay"> /// The kind of time prefix to apply to each chunk of output. /// </param> /// <param name="eventMask"> /// If specified, an EventMask that allows selectively enabling or disabling events /// </param> /// <param name="onDisabledDueToDiskWriteFailure"> /// If specified, called if the listener encounters a disk-write failure such as an out of space condition. /// Otherwise, such conditions will throw an exception. /// </param> /// <param name="pathTranslator"> /// If specified, translates paths from one root to another /// </param> /// <param name="listenDiagnosticMessages"> /// If true, all messages tagged with <see cref="Keywords.Diagnostics" /> at or above <paramref name="level"/> are enabled but not captured unless diagnostics are enabled per-task. /// This is useful for StatisticsEventListener, where you need to listen diagnostics messages but capture only ones tagged with CommonInfrastructure task. /// </param> public TextWriterEventListener( Events eventSource, IEventWriter writer, DateTime baseTime, WarningMapper warningMapper = null, EventLevel level = EventLevel.Verbose, TimeDisplay timeDisplay = TimeDisplay.None, EventMask eventMask = null, DisabledDueToDiskWriteFailureEventHandler onDisabledDueToDiskWriteFailure = null, PathTranslator pathTranslator = null, bool listenDiagnosticMessages = false) : base( eventSource, baseTime, warningMapper, level, false, timeDisplay, eventMask, onDisabledDueToDiskWriteFailure, listenDiagnosticMessages) { Contract.Requires(eventSource != null); Contract.Requires(writer != null); m_writer = writer; m_flushTimer = new StoppableTimer( SynchronizedFlush, (int)s_flushInterval.TotalMilliseconds, (int)s_flushInterval.TotalMilliseconds); m_translator = pathTranslator; }
/// <summary> /// Awaits for a given task while periodically calling <paramref name="action"/>. /// </summary> /// <typeparam name="TResult">Return type of the task</typeparam> /// <param name="task">The task to await</param> /// <param name="period">Period at which to call <paramref name="action"/></param> /// <param name="action">Action to periodically call. The action receives elapsed time since this method was called.</param> /// <param name="reportImmediately">Whether <paramref name="action"/> should be called immediately.</param> /// <param name="reportAtEnd">Whether <paramref name="action"/> should be called at when </param> /// <returns>The result of the task.</returns> public static async Task <TResult> AwaitWithProgressReporting <TResult>( Task <TResult> task, TimeSpan period, Action <TimeSpan> action, bool reportImmediately = true, bool reportAtEnd = true) { var startTime = DateTime.UtcNow; var timer = new StoppableTimer( () => { action(DateTime.UtcNow.Subtract(startTime)); }, dueTime: reportImmediately ? 0 : (int)period.TotalMilliseconds, period: (int)period.TotalMilliseconds); using (timer) { await task.ContinueWith(t => { return(timer.StopAsync()); }).Unwrap(); // report once at the end if (reportAtEnd) { action(DateTime.UtcNow.Subtract(startTime)); } return(await task); } }
/// <summary> /// Awaits given tasks, periodically calling <paramref name="action"/>. /// </summary> /// <typeparam name="TItem">Type of the collection to iterate over.</typeparam> /// <typeparam name="TResult">Type of the tasks' result.</typeparam> /// <param name="collection">Collection to iterate over.</param> /// <param name="taskSelector">Function to use to select a task for a given item from the given collection.</param> /// <param name="action"> /// Action to call periodically (as specified by <paramref name="period"/>). /// The action receives /// (1) total elapsed time, /// (2) all original items, and /// (3) a collection of non-finished items /// </param> /// <param name="period">Period at which to call <paramref name="action"/>.</param> /// <returns>The results of inidvidual tasks.</returns> public static async Task <TResult[]> AwaitWithProgressReporting <TItem, TResult>( IReadOnlyCollection <TItem> collection, Func <TItem, Task <TResult> > taskSelector, Action <TimeSpan, IReadOnlyCollection <TItem>, IReadOnlyCollection <TItem> > action, TimeSpan period) { var startTime = DateTime.UtcNow; var timer = new StoppableTimer( () => { var elapsed = DateTime.UtcNow.Subtract(startTime); var remainingItems = collection .Where(item => !taskSelector(item).IsCompleted) .ToList(); action(elapsed, collection, remainingItems); }, dueTime: 0, period: (int)period.TotalMilliseconds); using (timer) { var result = await Task.WhenAll(collection.Select(item => taskSelector(item))); await timer.StopAsync(); // report once at the end action(DateTime.UtcNow.Subtract(startTime), collection, CollectionUtilities.EmptyArray <TItem>()); return(result); } }
public PulsationAnalyzePage() { InitializeComponent(); Bluetooth = DependencyService.Get <Bluetooth>(); #if DEBUG _impulseInvoker = new MockImpulseInvoker(); #endif _vm = new DeviceDataViewModel(); _ddp = DeviceDataProvider.GetProvider; _timer = new StoppableTimer(TimeSpan.FromMilliseconds(Constants.UPDATE_INTERVAL), TimerTick); FirstChanelSeries.ItemsSource = _vm.FirstChanelSeriesData; SecondChanelSeries.ItemsSource = _vm.SecondChanelSeriesData; _jsonKeeper = new JsonDataKeeper <DeviceDataViewModel>(); }
private bool PersistFullBuild(IConfiguration configuration, PathTable pathTable, CancellationToken cancellationToken) { var snapshotFile = m_snapshotFile.ToString(pathTable); var mountFolder = snapshotFile + ".tmpdir"; try { // Find a drive to mount the VHD as for this process. The VHD will be mapped to a particular NTFS folder // and then mounted as a drive using the drive mapping functionality. This is done to avoid issues with MAX_PATH // issues since many codebases have paths nearing MAX_PATH which would go over if rooted in a subdirectory // of even a reasonably short path length. char unusedDrive = char.MinValue; var systemDriveLetter = SpecialFolderUtilities.SystemDirectory[0]; for (char drive = 'A'; drive <= 'Z'; drive++) { if (drive == systemDriveLetter || drive == 'C') { continue; } if (!AbsolutePath.TryGet(pathTable, new StringSegment(drive + @":\"), out _)) { unusedDrive = drive; } } if (unusedDrive == char.MinValue) { Tracing.Logger.Log.GenericSnapshotError(m_loggingContext, "Snapshot error: Could not find unused drive to use for snapshot destination"); return(false); } bool mounted = VhdUtilities.Mount(snapshotFile, sizeMb: 1 << 20 /* 1 TB */, mountFolder: mountFolder); if (!mounted) { Tracing.Logger.Log.GenericSnapshotError( m_loggingContext, I($"Snapshot error: Could not create VHD '{unusedDrive}' and mount at '{mountFolder}'")); return(false); } // Map drive for mounted vhd in order to minimize chance of MAX_PATH issues copying files to VHD. bool mappingApplied = ProcessNativeMethods.ApplyDriveMappings(new[] { new PathMapping(unusedDrive, Path.GetFullPath(mountFolder)) }); if (!mappingApplied) { Tracing.Logger.Log.GenericSnapshotError( m_loggingContext, I($"Snapshot error: Drive mapping could not be applied from '{unusedDrive}' to '{mountFolder}'")); return(false); } var mountDriveRoot = unusedDrive + @":\"; var buildEvaluationFiles = new HashSet <AbsolutePath>(m_files); if (configuration.Cache.CacheConfigFile.IsValid) { buildEvaluationFiles.Add(configuration.Cache.CacheConfigFile); } // Track used roots so mappings can be added for inputs and outputs when running BuildXL on snap ConcurrentDictionary <AbsolutePath, Unit> usedRoots = new ConcurrentDictionary <AbsolutePath, Unit>(); int capturedFileCount = 0; int totalFileCount = buildEvaluationFiles.Count + m_pipGraph.FileCount; Action updateStatus = () => { Console.WriteLine("Snapshot: {0} of {1} files captured", capturedFileCount, totalFileCount); }; updateStatus(); var t = new StoppableTimer(updateStatus, 5000, 5000); // Copy the build evaluation files Parallel.ForEach( buildEvaluationFiles.ToArray(), new ParallelOptions() { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = cancellationToken }, buildEvaluationFile => { usedRoots[buildEvaluationFile.GetRoot(pathTable)] = Unit.Void; CopyPath(pathTable, buildEvaluationFile, mountDriveRoot); Interlocked.Increment(ref capturedFileCount); }); if (m_pipGraph != null) { // Copy all source files Parallel.ForEach( m_pipGraph.AllFiles.ToArray(), new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount, CancellationToken = cancellationToken }, pipFile => { try { usedRoots[pipFile.Path.GetRoot(pathTable)] = Unit.Void; if (pipFile.IsOutputFile) { return; } if (!buildEvaluationFiles.Contains(pipFile.Path)) { CopyPath(pathTable, pipFile.Path, mountDriveRoot); } } finally { Interlocked.Increment(ref capturedFileCount); } }); } // kill and wait for the status timer to die... t.Dispose(); using (var writer = new StreamWriter(File.OpenWrite(Path.Combine(mountDriveRoot, "notes.txt")))) { writer.WriteLine("Full Build Snapshot Info"); writer.WriteLine(); WriteNotes(configuration, pathTable, writer, path => path.ToString(pathTable)); } using (var writer = new StreamWriter(File.OpenWrite(Path.Combine(mountDriveRoot, "runbxl.cmd")))) { writer.Write("%BUILDXL_EXE_PATH% \"@%~dp0\\buildxl.rsp\" %*"); foreach (var usedRoot in usedRoots.Keys) { var usedRootLetter = usedRoot.ToString(pathTable)[0]; if (usedRootLetter.ToUpperInvariantFast() == 'C') { continue; } Directory.CreateDirectory(Path.Combine(mountDriveRoot, usedRootLetter.ToString())); writer.Write(" /rootMap:{0}=\"%~dp0\\{0}\"", usedRootLetter); } } using (var writer = new StreamWriter(File.OpenWrite(Path.Combine(mountDriveRoot, "buildxl.rsp")))) { foreach (var argument in m_commandLineArguments) { writer.WriteLine(argument); } // Disable snapshot when running from snapshot writer.WriteLine("/snapshotMode:None"); foreach (var envVar in m_environmentVariables) { writer.WriteLine("/envVar:{0}={1}", envVar.Key, envVar.Value ?? string.Empty); } } } finally { Analysis.IgnoreResult(VhdUtilities.Dismount(snapshotFile, mountFolder)); // TODO: Report error. } return(true); }
public MockImpulseInvoker() { _dataProvider = DeviceDataProvider.GetProvider; _random = new Random(); _timer = new StoppableTimer(TimeSpan.FromSeconds(1), Callback); }