27

私はこのようなことを達成したいと思います:

Time consuming operation...OK
Another time consuming operation...
And another one, but it completed, so...OK

遅かれ早かれ終了する可能性のあるスレッドに関連する3行のテキストを表示しました。しかし、2番目のものが3番目のものより遅く完了すると、次のようになります。

Time consuming operation...OK
Another time consuming operation...
And another one, but it completed, so...OKOK

もちろん、これは受け入れられません。現在のラインに戻る方法は知っていますが、UPする方法はありますか?Linuxコンソールかもしれませんが、どこかで見たことがあると思います:)

忘れてください。Far File Managerを参照してください!Windowsコンソールで動作し、PowerShellでも動作します!このようなものを作る方法は?そして最もクールな部分は、終了後にコンソールの状態を復元することです。だから多分私は尋ねるべきです-コンソールバッファに直接アクセスする方法は?トリックを実行するにはネイティブコードが必要だと思いますが、別の方法があるのではないでしょうか。更新のたびにコンソールをクリアすることを考えましたが、これはやり過ぎのようです。または多分そうではありませんか?点滅しますか?

4

3 に答える 3

62

Console.SetCursorPositionまたはConsole.CursorTopを使用し、カーソルを好きな場所に移動できます。

Console.SetCursorPosition(0, Console.CursorTop -1);
Console.WriteLine("Over previous line!!!");
于 2012-05-29T17:57:34.577 に答える
8

キャリッジリターンを使用します。このサンプルは1行を印刷し、以前にあったものを上書きします。

  Console.WriteLine();
  for (int i = 0; i <= 100; i++)
  {
    System.Threading.Thread.Sleep(10);
    Console.Write("\x000DProgress: " + i);
  }

これは、すべての文字列が80列(またはターミナルバッファが設定されているもの)未満である限り機能します。

于 2012-05-29T18:01:27.393 に答える
1

注:次の回答は、元々OPによって質問に編集されました。


デモを使用した完全なソリューションは次のとおりです。

using System;
using System.Collections.Generic;
using System.Threading;

namespace PowerConsole {

    internal class Containers {

        internal struct Container {
            public int Id;
            public int X;
            public int Y;
            public string Content;
        }

        public static List<Container> Items = new List<Container>();

        private static int Identity = 0;

        public static int Add(string text) {
            var c = new Container();
            c.Id = Identity++;
            c.X = Console.CursorLeft;
            c.Y = Console.CursorTop;
            c.Content = text;
            Console.Write(text);
            Items.Add(c);
            return c.Id;
        }

        public static void Remove(int id) {
            Items.RemoveAt(id);
        }

        public static void Replace(int id, string text) {
            int x = Console.CursorLeft, y = Console.CursorTop;
            Container c = Items[id];
            Console.MoveBufferArea(
                c.X + c.Content.Length, c.Y,
                Console.BufferWidth - c.X - text.Length, 1,
                c.X + text.Length, c.Y
            );
            Console.CursorLeft = c.X;
            Console.CursorTop = c.Y;
            Console.Write(text);
            c.Content = text;
            Console.CursorLeft = x;
            Console.CursorTop = y;
        }

        public static void Clear() {
            Items.Clear();
            Identity = 0;
        }
    }

    internal class Program {
        private static List<Thread> Threads = new List<Thread>();

        private static void Main(string[] args) {
            Console.WriteLine("So we have some threads:\r\n");
            int i, id;
            Random r = new Random();
            for (i = 0; i < 10; i++) {
                Console.Write("Starting thread " + i + "...[");
                id = Containers.Add("?");
                Console.WriteLine("]");
                Thread t = new Thread((object data) => {
                    Thread.Sleep(r.Next(5000) + 100);
                    Console.ForegroundColor = ConsoleColor.Green;
                    Containers.Replace((int)data, "DONE");
                    Console.ResetColor();
                });
                Threads.Add(t);
            }
            Console.WriteLine("\n\"But will it blend?\"...");
            Console.ReadKey(true);
            i = 0;
            Threads.ForEach(t => t.Start(i++));
            Threads.ForEach(t => t.Join());
            Console.WriteLine("\r\nVoila.");
            Console.ReadKey(true);
        }
    }
}
于 2016-11-15T14:57:33.343 に答える