Console.setcursorposition j 5 i 4 là gì năm 2024

After removing the call to move() between the Console.Write and Console.WriteLine calls, there are 4 calls to TCGETS and none to TCSETS.

Are you sure those TCGETS are coming from this code? I don't see anything on our Console.Write paths that would cause a TCGET.

The calls to TCSETS happen from SystemNative_InitializeConsoleBeforeRead.

Presumably so do the TCGETS?

I'd have expected those to be all of the TCGETS, and then to see TCSETS coming from:

and

So, 2 calls to TCSETS makes sense to me (one for setup, one for cleanup). I'd expect 1 TCGET here in addition. So if those 4 other TCGETS were coming from something else, such as the terminal validating state before and after executing the program, or something to do with the dotnet host, or some such thing, then the numbers make sense to me, 2 TCSETS and 1 TCGET per call to either CursorLeft or CursorTop.

it means we do 5 calls to TCGETS and 2 calls to TCSETS per each cursor position read

Part of the problem is we don't expose a way to get both the "Left" and "Top" at the same time; exposing that would cut the number in half. That's covered by: //github.com/dotnet/corefx/issues/34885 cc: @wtgodbe

so I am not sure if we can reduce the number of syscalls in any way or not.

Assuming I'm right about the 2+1 above, I'm not sure there's much we can do unless we rearchitect how we handle all of this. There are two related pieces here that come up not infrequently:

  1. How we handle echo / tty settings
  2. How we handle getting the current cursor position

For (1): //github.com/dotnet/corefx/issues/34501

For (2): //github.com/dotnet/corefx/issues/31517

I can confirm that Mono doesn't have any issue.

Mono tries to cache the current cursor position, such that CursorLeft and CursorTop hand back the cached value. That makes getting the current position super fast, which is awesome, but it can lead to correctness problems if anything that's not being monitored invalidates the cached notion of where it currently is. For example, it doesn't monitor terminal scrolling / resizing with regards to cursor position, so try a program like this:

using System; using System.Threading; class Program {public static void Main() { while (true) { Thread.Sleep(1000); Console.WriteLine(Console.CursorLeft + ", " + Console.CursorTop); } } }

let it output a few lines, and then shrink the window by pushing up the bottom of the terminal such that the terminal is only a few lines tall. It'll continue to still say the position is what it was, because it's pulling it from its cache that wasn't invalidated.

That's not casting aspersions at Mono, just highlighting that there are difficulties here. Of course as has been pointed out, Mono's implementation of CursorTop/Left is way faster when compared to the current implementation in corefx, and it's only the corner-cases that break, so it may very well be that it's following the right approach, corefx is in the wrong, and we should pursue this route instead. It comes up enough. We just need to do real due diligence in making sure that we are aggressive about invalidating the cache when anything that could impact it happens; we should be able to do that, though, we just need a lot of eyes on it to make sure nothing slips through the gaps.

Upgrade to Microsoft Edge to take advantage of the latest features, security updates, and technical support.

Console.CursorTop Property

  • Reference

Definition

Gets or sets the row position of the cursor within the buffer area. public: static property int CursorTop { int get(); void set(int value); }; [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] public static int CursorTop { get; set; } [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] [System.Runtime.Versioning.UnsupportedOSPlatform("android")] [System.Runtime.Versioning.UnsupportedOSPlatform("ios")] [System.Runtime.Versioning.UnsupportedOSPlatform("tvos")] public static int CursorTop { get; set; } public static int CursorTop { get; set; } [<System.Runtime.Versioning.UnsupportedOSPlatform("browser")>] static member CursorTop : int with get, set [<System.Runtime.Versioning.UnsupportedOSPlatform("browser")>] [<System.Runtime.Versioning.UnsupportedOSPlatform("android")>] [<System.Runtime.Versioning.UnsupportedOSPlatform("ios")>] [<System.Runtime.Versioning.UnsupportedOSPlatform("tvos")>] static member CursorTop : int with get, set static member CursorTop : int with get, set Public Shared Property CursorTop As Integer

Property Value

The current position, in rows, of the cursor.

Attributes

Exceptions

The value in a set operation is less than zero.

-or-

The value in a set operation is greater than or equal to .

The user does not have permission to perform this action.

Examples

This example demonstrates the CursorLeft and CursorTop properties, and the SetCursorPosition and Clear methods. The example positions the cursor, which determines where the next write will occur, to draw a 5 character by 5 character rectangle using a combination of "+", "|", and "-" strings. Note that the rectangle could be drawn with fewer steps using a combination of other strings.

`// This example demonstrates the // Console.CursorLeft and // Console.CursorTop properties, and the // Console.SetCursorPosition and // Console.Clear methods. using namespace System; int origRow; int origCol; void WriteAt( String^ s, int x, int y ) { try { Console::SetCursorPosition( origCol + x, origRow + y ); Console::Write( s ); } catch ( ArgumentOutOfRangeException^ e ) { Console::Clear(); Console::WriteLine( e->Message ); } } int main() { // Clear the screen, then save the top and left coordinates. Console::Clear(); origRow = Console::CursorTop; origCol = Console::CursorLeft; // Draw the left side of a 5x5 rectangle, from top to bottom. WriteAt( "+", 0, 0 ); WriteAt( "|", 0, 1 ); WriteAt( "|", 0, 2 ); WriteAt( "|", 0, 3 ); WriteAt( "+", 0, 4 ); // Draw the bottom side, from left to right. WriteAt( "-", 1, 4 ); // shortcut: WriteAt("-", 1, 4) WriteAt( "-", 2, 4 ); // ... WriteAt( "-", 3, 4 ); // ... WriteAt( "+", 4, 4 ); // Draw the right side, from bottom to top. WriteAt( "|", 4, 3 ); WriteAt( "|", 4, 2 ); WriteAt( "|", 4, 1 ); WriteAt( "+", 4, 0 ); // Draw the top side, from right to left. WriteAt( "-", 3, 0 ); // shortcut: WriteAt("-", 1, 0) WriteAt( "-", 2, 0 ); // ... WriteAt( "-", 1, 0 ); // ... // WriteAt( "All done!", 0, 6 ); Console::WriteLine(); } /* This example produces the following results: +---+

+---+

All done! */ `

`// This example demonstrates the // Console.CursorLeft and // Console.CursorTop properties, and the // Console.SetCursorPosition and // Console.Clear methods. using System; class Sample {protected static int origRow; protected static int origCol; protected static void WriteAt(string s, int x, int y) { try { Console.SetCursorPosition(origCol+x, origRow+y); Console.Write(s); } catch (ArgumentOutOfRangeException e) { Console.Clear(); Console.WriteLine(e.Message); } } public static void Main() { // Clear the screen, then save the top and left coordinates.Console.Clear(); origRow = Console.CursorTop; origCol = Console.CursorLeft; // Draw the left side of a 5x5 rectangle, from top to bottom.WriteAt("+", 0, 0); WriteAt("|", 0, 1); WriteAt("|", 0, 2); WriteAt("|", 0, 3); WriteAt("+", 0, 4); // Draw the bottom side, from left to right.WriteAt("-", 1, 4); // shortcut: WriteAt("---", 1, 4) WriteAt("-", 2, 4); // ... WriteAt("-", 3, 4); // ... WriteAt("+", 4, 4); // Draw the right side, from bottom to top.WriteAt("|", 4, 3); WriteAt("|", 4, 2); WriteAt("|", 4, 1); WriteAt("+", 4, 0); // Draw the top side, from right to left.WriteAt("-", 3, 0); // shortcut: WriteAt("---", 1, 0) WriteAt("-", 2, 0); // ... WriteAt("-", 1, 0); // ... //WriteAt("All done!", 0, 6); Console.WriteLine(); } } /* This example produces the following results: +---+

+---+

All done! */ ` [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] public static int CursorTop { get; set; }

0 [System.Runtime.Versioning.UnsupportedOSPlatform("browser")] public static int CursorTop { get; set; }

1

Applies to

Collaborate with us on GitHub

The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, see our contributor guide.

Chủ đề