private async Task ResizeTask() { while (true) { TimeSpan delay; TerminalSize size = null; lock (_resizeLock) { if (_requestedSize?.EquivalentTo(_setSize) ?? true) { // Resize finished. Unblock output and exit. if (_outputBlockedBuffer != null) { OnOutput?.Invoke(this, _outputBlockedBuffer.ToArray()); _outputBlockedBuffer.Dispose(); _outputBlockedBuffer = null; } _resizeTask = null; break; } delay = _resizeScheduleTime.Subtract(DateTime.UtcNow); // To avoid sleeping for only few milliseconds we're introducing a threshold of 10 milliseconds if (delay.TotalMilliseconds < 10) { _setSize = size = _requestedSize; if (_outputBlockedBuffer == null) { _outputBlockedBuffer = new MemoryStream(); } } } if (size == null) { await Task.Delay(delay).ConfigureAwait(false); } else { await ViewModel.Terminal.SetSizeAsync(_requestedSize).ConfigureAwait(false); } } }
// Must be called from a code locked with _resizeLock private void ScheduleResize(TerminalSize size, bool scheduleIfEqual) { if (!scheduleIfEqual && size.EquivalentTo(_requestedSize)) { return; } _requestedSize = size; _resizeScheduleTime = DateTime.UtcNow.Add(ResizeDelay); if (_resizeTask == null) { _resizeTask = ResizeTask(); } }