3 // Copyright (c) Microsoft Corporation. All rights reserved.
6 /*============================================================
10 ** <OWNER>[....]</OWNER>
13 ** Purpose: Abstract base class for Text-only Writers.
14 ** Subclasses will include StreamWriter & StringWriter.
17 ===========================================================*/
21 using System
.Threading
;
22 using System
.Runtime
.CompilerServices
;
23 using System
.Runtime
.InteropServices
;
24 using System
.Reflection
;
25 using System
.Security
.Permissions
;
26 using System
.Globalization
;
27 using System
.Diagnostics
.CodeAnalysis
;
28 using System
.Diagnostics
.Contracts
;
30 using System
.Threading
.Tasks
;
34 // This abstract base class represents a writer that can write a sequential
35 // stream of characters. A subclass must minimally implement the
36 // Write(char) method.
38 // This class is intended for character output, not bytes.
39 // There are methods on the Stream class for writing bytes.
43 public abstract class TextWriter
: MarshalByRefObject
, IDisposable
{
44 #else // FEATURE_REMOTING
45 public abstract class TextWriter
: IDisposable
{
46 #endif // FEATURE_REMOTING
47 public static readonly TextWriter Null
= new NullTextWriter();
51 private static Action
<object> _WriteCharDelegate
= state
=>
53 Tuple
<TextWriter
, char> tuple
= (Tuple
<TextWriter
, char>)state
;
54 tuple
.Item1
.Write(tuple
.Item2
);
58 private static Action
<object> _WriteStringDelegate
= state
=>
60 Tuple
<TextWriter
, string> tuple
= (Tuple
<TextWriter
, string>)state
;
61 tuple
.Item1
.Write(tuple
.Item2
);
65 private static Action
<object> _WriteCharArrayRangeDelegate
= state
=>
67 Tuple
<TextWriter
, char[], int, int> tuple
= (Tuple
<TextWriter
, char[],int, int>)state
;
68 tuple
.Item1
.Write(tuple
.Item2
, tuple
.Item3
, tuple
.Item4
);
72 private static Action
<object> _WriteLineCharDelegate
= state
=>
74 Tuple
<TextWriter
, char> tuple
= (Tuple
<TextWriter
, char>)state
;
75 tuple
.Item1
.WriteLine(tuple
.Item2
);
79 private static Action
<object> _WriteLineStringDelegate
= state
=>
81 Tuple
<TextWriter
, string> tuple
= (Tuple
<TextWriter
, string>)state
;
82 tuple
.Item1
.WriteLine(tuple
.Item2
);
86 private static Action
<object> _WriteLineCharArrayRangeDelegate
= state
=>
88 Tuple
<TextWriter
, char[], int, int> tuple
= (Tuple
<TextWriter
, char[],int, int>)state
;
89 tuple
.Item1
.WriteLine(tuple
.Item2
, tuple
.Item3
, tuple
.Item4
);
93 private static Action
<object> _FlushDelegate
= state
=> ((TextWriter
)state
).Flush();
96 // This should be initialized to Environment.NewLine, but
97 // to avoid loading Environment unnecessarily so I've duplicated
100 static string InitialNewLine
{
102 return Environment
.NewLine
;
106 protected char[] CoreNewLine
= InitialNewLine
.ToCharArray ();
109 private const String InitialNewLine
= "\r\n";
111 protected char[] CoreNewLine
= new char[] { '\r', '\n' }
;
113 private const String InitialNewLine
= "\n";
115 protected char[] CoreNewLine
= new char[] {'\n'}
;
117 #endif // !PLATFORM_UNIX
119 // Can be null - if so, ask for the Thread's CurrentCulture every time.
120 private IFormatProvider InternalFormatProvider
;
122 protected TextWriter()
124 InternalFormatProvider
= null; // Ask for CurrentCulture all the time.
127 protected TextWriter(IFormatProvider formatProvider
)
129 InternalFormatProvider
= formatProvider
;
132 public virtual IFormatProvider FormatProvider
{
134 if (InternalFormatProvider
== null)
135 return Thread
.CurrentThread
.CurrentCulture
;
137 return InternalFormatProvider
;
141 // Closes this TextWriter and releases any system resources associated with the
142 // TextWriter. Following a call to Close, any operations on the TextWriter
143 // may raise exceptions. This default method is empty, but descendant
144 // classes can override the method to provide the appropriate
146 public virtual void Close() {
148 GC
.SuppressFinalize(this);
151 protected virtual void Dispose(bool disposing
)
156 public void Dispose()
159 GC
.SuppressFinalize(this);
162 // Clears all buffers for this TextWriter and causes any buffered data to be
163 // written to the underlying device. This default method is empty, but
164 // descendant classes can override the method to provide the appropriate
166 public virtual void Flush() {
169 public abstract Encoding Encoding
{
173 // Returns the line terminator string used by this TextWriter. The default line
174 // terminator string is a carriage return followed by a line feed ("\r\n").
176 // Sets the line terminator string for this TextWriter. The line terminator
177 // string is written to the text stream whenever one of the
178 // WriteLine methods are called. In order for text written by
179 // the TextWriter to be readable by a TextReader, only one of the following line
180 // terminator strings should be used: "\r", "\n", or "\r\n".
182 public virtual String NewLine
{
183 get { return new String(CoreNewLine); }
186 value = InitialNewLine
;
187 CoreNewLine
= value.ToCharArray();
192 [HostProtection(Synchronization
=true)]
193 public static TextWriter
Synchronized(TextWriter writer
) {
195 throw new ArgumentNullException("writer");
196 Contract
.Ensures(Contract
.Result
<TextWriter
>() != null);
197 Contract
.EndContractBlock();
199 if (writer
is SyncTextWriter
)
202 return new SyncTextWriter(writer
);
205 // Writes a character to the text stream. This default method is empty,
206 // but descendant classes can override the method to provide the
207 // appropriate functionality.
209 public virtual void Write(char value) {
212 // Writes a character array to the text stream. This default method calls
213 // Write(char) for each of the characters in the character array.
214 // If the character array is null, nothing is written.
216 public virtual void Write(char[] buffer
) {
217 if (buffer
!= null) Write(buffer
, 0, buffer
.Length
);
220 // Writes a range of a character array to the text stream. This method will
221 // write count characters of data into this TextWriter from the
222 // buffer character array starting at position index.
224 public virtual void Write(char[] buffer
, int index
, int count
) {
226 throw new ArgumentNullException("buffer", Environment
.GetResourceString("ArgumentNull_Buffer"));
228 throw new ArgumentOutOfRangeException("index", Environment
.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
230 throw new ArgumentOutOfRangeException("count", Environment
.GetResourceString("ArgumentOutOfRange_NeedNonNegNum"));
231 if (buffer
.Length
- index
< count
)
232 throw new ArgumentException(Environment
.GetResourceString("Argument_InvalidOffLen"));
233 Contract
.EndContractBlock();
235 for (int i
= 0; i
< count
; i
++) Write(buffer
[index
+ i
]);
238 // Writes the text representation of a boolean to the text stream. This
239 // method outputs either Boolean.TrueString or Boolean.FalseString.
241 public virtual void Write(bool value) {
242 Write(value ? Boolean
.TrueLiteral
: Boolean
.FalseLiteral
);
245 // Writes the text representation of an integer to the text stream. The
246 // text representation of the given value is produced by calling the
247 // Int32.ToString() method.
249 public virtual void Write(int value) {
250 Write(value.ToString(FormatProvider
));
253 // Writes the text representation of an integer to the text stream. The
254 // text representation of the given value is produced by calling the
255 // UInt32.ToString() method.
257 [CLSCompliant(false)]
258 public virtual void Write(uint value) {
259 Write(value.ToString(FormatProvider
));
262 // Writes the text representation of a long to the text stream. The
263 // text representation of the given value is produced by calling the
264 // Int64.ToString() method.
266 public virtual void Write(long value) {
267 Write(value.ToString(FormatProvider
));
270 // Writes the text representation of an unsigned long to the text
271 // stream. The text representation of the given value is produced
272 // by calling the UInt64.ToString() method.
274 [CLSCompliant(false)]
275 public virtual void Write(ulong value) {
276 Write(value.ToString(FormatProvider
));
279 // Writes the text representation of a float to the text stream. The
280 // text representation of the given value is produced by calling the
281 // Float.toString(float) method.
283 public virtual void Write(float value) {
284 Write(value.ToString(FormatProvider
));
287 // Writes the text representation of a double to the text stream. The
288 // text representation of the given value is produced by calling the
289 // Double.toString(double) method.
291 public virtual void Write(double value) {
292 Write(value.ToString(FormatProvider
));
295 public virtual void Write(Decimal
value) {
296 Write(value.ToString(FormatProvider
));
299 // Writes a string to the text stream. If the given string is null, nothing
300 // is written to the text stream.
302 public virtual void Write(String
value) {
303 if (value != null) Write(value.ToCharArray());
306 // Writes the text representation of an object to the text stream. If the
307 // given object is null, nothing is written to the text stream.
308 // Otherwise, the object's ToString method is called to produce the
309 // string representation, and the resulting string is then written to the
312 public virtual void Write(Object
value) {
314 IFormattable f
= value as IFormattable
;
316 Write(f
.ToString(null, FormatProvider
));
318 Write(value.ToString());
323 // // Converts the wchar * to a string and writes this to the stream.
325 // __attribute NonCLSCompliantAttribute()
326 // public void Write(wchar *value) {
327 // Write(new String(value));
330 // // Treats the byte* as a LPCSTR, converts it to a string, and writes it to the stream.
332 // __attribute NonCLSCompliantAttribute()
333 // public void Write(byte *value) {
334 // Write(new String(value));
339 // Writes out a formatted string. Uses the same semantics as
342 public virtual void Write(String format
, Object arg0
)
344 Write(String
.Format(FormatProvider
, format
, arg0
));
347 // Writes out a formatted string. Uses the same semantics as
350 public virtual void Write(String format
, Object arg0
, Object arg1
)
352 Write(String
.Format(FormatProvider
, format
, arg0
, arg1
));
355 // Writes out a formatted string. Uses the same semantics as
358 public virtual void Write(String format
, Object arg0
, Object arg1
, Object arg2
)
360 Write(String
.Format(FormatProvider
, format
, arg0
, arg1
, arg2
));
363 // Writes out a formatted string. Uses the same semantics as
366 public virtual void Write(String format
, params Object
[] arg
)
368 Write(String
.Format(FormatProvider
, format
, arg
));
372 // Writes a line terminator to the text stream. The default line terminator
373 // is a carriage return followed by a line feed ("\r\n"), but this value
374 // can be changed by setting the NewLine property.
376 public virtual void WriteLine() {
380 // Writes a character followed by a line terminator to the text stream.
382 public virtual void WriteLine(char value) {
387 // Writes an array of characters followed by a line terminator to the text
390 public virtual void WriteLine(char[] buffer
) {
395 // Writes a range of a character array followed by a line terminator to the
398 public virtual void WriteLine(char[] buffer
, int index
, int count
) {
399 Write(buffer
, index
, count
);
403 // Writes the text representation of a boolean followed by a line
404 // terminator to the text stream.
406 public virtual void WriteLine(bool value) {
411 // Writes the text representation of an integer followed by a line
412 // terminator to the text stream.
414 public virtual void WriteLine(int value) {
419 // Writes the text representation of an unsigned integer followed by
420 // a line terminator to the text stream.
422 [CLSCompliant(false)]
423 public virtual void WriteLine(uint value) {
428 // Writes the text representation of a long followed by a line terminator
429 // to the text stream.
431 public virtual void WriteLine(long value) {
436 // Writes the text representation of an unsigned long followed by
437 // a line terminator to the text stream.
439 [CLSCompliant(false)]
440 public virtual void WriteLine(ulong value) {
445 // Writes the text representation of a float followed by a line terminator
446 // to the text stream.
448 public virtual void WriteLine(float value) {
453 // Writes the text representation of a double followed by a line terminator
454 // to the text stream.
456 public virtual void WriteLine(double value) {
461 public virtual void WriteLine(decimal value) {
466 // Writes a string followed by a line terminator to the text stream.
468 public virtual void WriteLine(String
value) {
474 // We'd ideally like WriteLine to be atomic, in that one call
475 // to WriteLine equals one call to the OS (ie, so writing to
476 // console while simultaneously calling printf will guarantee we
477 // write out a string and new line chars, without any interference).
478 // Additionally, we need to call ToCharArray on Strings anyways,
479 // so allocating a char[] here isn't any worse than what we were
480 // doing anyways. We do reduce the number of calls to the
481 // backing store this way, potentially.
482 int vLen
= value.Length
;
483 int nlLen
= CoreNewLine
.Length
;
484 char[] chars
= new char[vLen
+nlLen
];
485 value.CopyTo(0, chars
, 0, vLen
);
486 // CoreNewLine will almost always be 2 chars, and possibly 1.
488 chars
[vLen
] = CoreNewLine
[0];
489 chars
[vLen
+1] = CoreNewLine
[1];
492 chars
[vLen
] = CoreNewLine
[0];
494 Buffer
.InternalBlockCopy(CoreNewLine
, 0, chars
, vLen
* 2, nlLen
* 2);
495 Write(chars
, 0, vLen
+ nlLen
);
498 Write(value); // We could call Write(String) on StreamWriter...
503 // Writes the text representation of an object followed by a line
504 // terminator to the text stream.
506 public virtual void WriteLine(Object
value) {
511 // Call WriteLine(value.ToString), not Write(Object), WriteLine().
512 // This makes calls to WriteLine(Object) atomic.
513 IFormattable f
= value as IFormattable
;
515 WriteLine(f
.ToString(null, FormatProvider
));
517 WriteLine(value.ToString());
521 // Writes out a formatted string and a new line. Uses the same
522 // semantics as String.Format.
524 public virtual void WriteLine(String format
, Object arg0
)
526 WriteLine(String
.Format(FormatProvider
, format
, arg0
));
529 // Writes out a formatted string and a new line. Uses the same
530 // semantics as String.Format.
532 public virtual void WriteLine (String format
, Object arg0
, Object arg1
)
534 WriteLine(String
.Format(FormatProvider
, format
, arg0
, arg1
));
537 // Writes out a formatted string and a new line. Uses the same
538 // semantics as String.Format.
540 public virtual void WriteLine (String format
, Object arg0
, Object arg1
, Object arg2
)
542 WriteLine(String
.Format(FormatProvider
, format
, arg0
, arg1
, arg2
));
545 // Writes out a formatted string and a new line. Uses the same
546 // semantics as String.Format.
548 public virtual void WriteLine (String format
, params Object
[] arg
)
550 WriteLine(String
.Format(FormatProvider
, format
, arg
));
554 #region Task based Async APIs
555 [HostProtection(ExternalThreading
= true)]
557 public virtual Task
WriteAsync(char value)
559 Tuple
<TextWriter
, char> tuple
= new Tuple
<TextWriter
, char>(this, value);
560 return Task
.Factory
.StartNew(_WriteCharDelegate
, tuple
, CancellationToken
.None
, TaskCreationOptions
.DenyChildAttach
, TaskScheduler
.Default
);
563 [HostProtection(ExternalThreading
= true)]
565 public virtual Task
WriteAsync(String
value)
567 Tuple
<TextWriter
, string> tuple
= new Tuple
<TextWriter
, string>(this, value);
568 return Task
.Factory
.StartNew(_WriteStringDelegate
, tuple
, CancellationToken
.None
, TaskCreationOptions
.DenyChildAttach
, TaskScheduler
.Default
);
571 [HostProtection(ExternalThreading
= true)]
573 public Task
WriteAsync(char[] buffer
)
575 if (buffer
== null) return Task
.CompletedTask
;
576 return WriteAsync(buffer
, 0, buffer
.Length
);
579 [HostProtection(ExternalThreading
= true)]
581 public virtual Task
WriteAsync(char[] buffer
, int index
, int count
)
583 Tuple
<TextWriter
, char[], int, int> tuple
= new Tuple
<TextWriter
, char[], int, int>(this, buffer
, index
, count
);
584 return Task
.Factory
.StartNew(_WriteCharArrayRangeDelegate
, tuple
, CancellationToken
.None
, TaskCreationOptions
.DenyChildAttach
, TaskScheduler
.Default
);
587 [HostProtection(ExternalThreading
= true)]
589 public virtual Task
WriteLineAsync(char value)
591 Tuple
<TextWriter
, char> tuple
= new Tuple
<TextWriter
, char>(this, value);
592 return Task
.Factory
.StartNew(_WriteLineCharDelegate
, tuple
, CancellationToken
.None
, TaskCreationOptions
.DenyChildAttach
, TaskScheduler
.Default
);
595 [HostProtection(ExternalThreading
= true)]
597 public virtual Task
WriteLineAsync(String
value)
599 Tuple
<TextWriter
, string> tuple
= new Tuple
<TextWriter
, string>(this, value);
600 return Task
.Factory
.StartNew(_WriteLineStringDelegate
, tuple
, CancellationToken
.None
, TaskCreationOptions
.DenyChildAttach
, TaskScheduler
.Default
);
603 [HostProtection(ExternalThreading
= true)]
605 public Task
WriteLineAsync(char[] buffer
)
607 if (buffer
== null) return Task
.CompletedTask
;
608 return WriteLineAsync(buffer
, 0, buffer
.Length
);
611 [HostProtection(ExternalThreading
= true)]
613 public virtual Task
WriteLineAsync(char[] buffer
, int index
, int count
)
615 Tuple
<TextWriter
, char[], int, int> tuple
= new Tuple
<TextWriter
, char[], int, int>(this, buffer
, index
, count
);
616 return Task
.Factory
.StartNew(_WriteLineCharArrayRangeDelegate
, tuple
, CancellationToken
.None
, TaskCreationOptions
.DenyChildAttach
, TaskScheduler
.Default
);
619 [HostProtection(ExternalThreading
= true)]
621 public virtual Task
WriteLineAsync()
623 return WriteAsync(CoreNewLine
);
626 [HostProtection(ExternalThreading
= true)]
628 public virtual Task
FlushAsync()
630 return Task
.Factory
.StartNew(_FlushDelegate
, this, CancellationToken
.None
, TaskCreationOptions
.DenyChildAttach
, TaskScheduler
.Default
);
633 #endif //FEATURE_ASYNC_IO
636 private sealed class NullTextWriter
: TextWriter
638 internal NullTextWriter(): base(CultureInfo
.InvariantCulture
) {
641 public override Encoding Encoding
{
642 get { return Encoding.Default; }
645 [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
646 public override void Write(char[] buffer
, int index
, int count
) {
649 public override void Write(String
value) {
652 // Not strictly necessary, but for perf reasons
653 public override void WriteLine() {
656 // Not strictly necessary, but for perf reasons
657 public override void WriteLine(String
value) {
660 public override void WriteLine(Object
value) {
665 internal sealed class SyncTextWriter
: TextWriter
, IDisposable
667 private TextWriter _out
;
669 internal SyncTextWriter(TextWriter t
): base(t
.FormatProvider
) {
673 public override Encoding Encoding
{
674 get { return _out.Encoding; }
677 public override IFormatProvider FormatProvider
{
678 get { return _out.FormatProvider; }
681 public override String NewLine
{
682 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
683 get { return _out.NewLine; }
684 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
685 set { _out.NewLine = value; }
688 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
689 public override void Close() {
690 // So that any overriden Close() gets run
694 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
695 protected override void Dispose(bool disposing
) {
696 // Explicitly pick up a potentially methodimpl'ed Dispose
698 ((IDisposable
)_out
).Dispose();
701 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
702 public override void Flush() {
706 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
707 public override void Write(char value) {
711 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
712 public override void Write(char[] buffer
) {
716 [SuppressMessage("Microsoft.Contracts", "CC1055")] // Skip extra error checking to avoid *potential* AppCompat problems.
717 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
718 public override void Write(char[] buffer
, int index
, int count
) {
719 _out
.Write(buffer
, index
, count
);
722 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
723 public override void Write(bool value) {
727 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
728 public override void Write(int value) {
732 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
733 public override void Write(uint value) {
737 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
738 public override void Write(long value) {
742 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
743 public override void Write(ulong value) {
747 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
748 public override void Write(float value) {
752 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
753 public override void Write(double value) {
757 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
758 public override void Write(Decimal
value) {
762 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
763 public override void Write(String
value) {
767 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
768 public override void Write(Object
value) {
772 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
773 public override void Write(String format
, Object arg0
) {
774 _out
.Write(format
, arg0
);
777 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
778 public override void Write(String format
, Object arg0
, Object arg1
) {
779 _out
.Write(format
, arg0
, arg1
);
782 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
783 public override void Write(String format
, Object arg0
, Object arg1
, Object arg2
) {
784 _out
.Write(format
, arg0
, arg1
, arg2
);
787 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
788 public override void Write(String format
, Object
[] arg
) {
789 _out
.Write(format
, arg
);
792 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
793 public override void WriteLine() {
797 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
798 public override void WriteLine(char value) {
799 _out
.WriteLine(value);
802 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
803 public override void WriteLine(decimal value) {
804 _out
.WriteLine(value);
807 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
808 public override void WriteLine(char[] buffer
) {
809 _out
.WriteLine(buffer
);
812 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
813 public override void WriteLine(char[] buffer
, int index
, int count
) {
814 _out
.WriteLine(buffer
, index
, count
);
817 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
818 public override void WriteLine(bool value) {
819 _out
.WriteLine(value);
822 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
823 public override void WriteLine(int value) {
824 _out
.WriteLine(value);
827 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
828 public override void WriteLine(uint value) {
829 _out
.WriteLine(value);
832 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
833 public override void WriteLine(long value) {
834 _out
.WriteLine(value);
837 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
838 public override void WriteLine(ulong value) {
839 _out
.WriteLine(value);
842 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
843 public override void WriteLine(float value) {
844 _out
.WriteLine(value);
847 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
848 public override void WriteLine(double value) {
849 _out
.WriteLine(value);
852 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
853 public override void WriteLine(String
value) {
854 _out
.WriteLine(value);
857 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
858 public override void WriteLine(Object
value) {
859 _out
.WriteLine(value);
862 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
863 public override void WriteLine(String format
, Object arg0
) {
864 _out
.WriteLine(format
, arg0
);
867 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
868 public override void WriteLine(String format
, Object arg0
, Object arg1
) {
869 _out
.WriteLine(format
, arg0
, arg1
);
872 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
873 public override void WriteLine(String format
, Object arg0
, Object arg1
, Object arg2
) {
874 _out
.WriteLine(format
, arg0
, arg1
, arg2
);
877 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
878 public override void WriteLine(String format
, Object
[] arg
) {
879 _out
.WriteLine(format
, arg
);
885 // On SyncTextWriter all APIs should run synchronously, even the async ones.
888 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
890 public override Task
WriteAsync(char value)
893 return Task
.CompletedTask
;
896 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
898 public override Task
WriteAsync(String
value)
901 return Task
.CompletedTask
;
904 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
906 public override Task
WriteAsync(char[] buffer
, int index
, int count
)
908 Write(buffer
, index
, count
);
909 return Task
.CompletedTask
;
912 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
914 public override Task
WriteLineAsync(char value)
917 return Task
.CompletedTask
;
920 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
922 public override Task
WriteLineAsync(String
value)
925 return Task
.CompletedTask
;
928 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
930 public override Task
WriteLineAsync(char[] buffer
, int index
, int count
)
932 WriteLine(buffer
, index
, count
);
933 return Task
.CompletedTask
;
936 [MethodImplAttribute(MethodImplOptions
.Synchronized
)]
938 public override Task
FlushAsync()
941 return Task
.CompletedTask
;
943 #endif //FEATURE_ASYNC_IO