| File: System\IO\SyncTextReader.cs | Web Access |
| Project: src\runtime\src\libraries\System.Console\src\System.Console.csproj (System.Console) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; namespace System.IO { /* SyncTextReader intentionally locks on itself rather than a private lock object. * This is done to synchronize different console readers (https://github.com/dotnet/corefx/pull/2855). */ internal sealed partial class SyncTextReader : TextReader { internal readonly TextReader _in; public static SyncTextReader GetSynchronizedTextReader(TextReader reader) { Debug.Assert(reader != null); return reader as SyncTextReader ?? new SyncTextReader(reader); } internal SyncTextReader(TextReader t) { _in = t; } protected override void Dispose(bool disposing) { if (disposing) { lock (this) { _in.Dispose(); } } } public override int Peek() { lock (this) { return _in.Peek(); } } public override int Read() { lock (this) { return _in.Read(); } } public override int Read(char[] buffer, int index, int count) { lock (this) { return _in.Read(buffer, index, count); } } public override int ReadBlock(char[] buffer, int index, int count) { lock (this) { return _in.ReadBlock(buffer, index, count); } } public override string? ReadLine() { lock (this) { return _in.ReadLine(); } } public override string ReadToEnd() { lock (this) { return _in.ReadToEnd(); } } // // On SyncTextReader all APIs should run synchronously, even the async ones. // No explicit locking is needed, as they all just delegate // public override Task<string?> ReadLineAsync() { return Task.FromResult(ReadLine()); } public override ValueTask<string?> ReadLineAsync(CancellationToken cancellationToken) { return cancellationToken.IsCancellationRequested ? ValueTask.FromCanceled<string?>(cancellationToken) : new ValueTask<string?>(ReadLine()); } public override Task<string> ReadToEndAsync() { return Task.FromResult(ReadToEnd()); } public override Task<string> ReadToEndAsync(CancellationToken cancellationToken) { return cancellationToken.IsCancellationRequested ? Task.FromCanceled<string>(cancellationToken) : Task.FromResult(ReadToEnd()); } public override Task<int> ReadBlockAsync(char[] buffer, int index, int count) { ArgumentNullException.ThrowIfNull(buffer); ArgumentOutOfRangeException.ThrowIfNegative(index); ArgumentOutOfRangeException.ThrowIfNegative(count); if (buffer.Length - index < count) throw new ArgumentException(SR.Argument_InvalidOffLen); return Task.FromResult(ReadBlock(buffer, index, count)); } public override Task<int> ReadAsync(char[] buffer, int index, int count) { ArgumentNullException.ThrowIfNull(buffer); ArgumentOutOfRangeException.ThrowIfNegative(index); ArgumentOutOfRangeException.ThrowIfNegative(count); if (buffer.Length - index < count) throw new ArgumentException(SR.Argument_InvalidOffLen); return Task.FromResult(Read(buffer, index, count)); } } }