いろいろ備忘録日記

主に .NET とか Go とか Flutter とか Python絡みのメモを公開しています。

コンソールで処理中であることを示す文字を表示 (System.Console, 処理中, SetCursorPosition, CusorLeft, CursorTop, Task.Factory.StartNew)


コンソールで処理中を表す際に、よく「.」の表示が行われていたりします。
一定時間経過するごとに、「.」を表示していって利用者に今処理中であることを
示します。


それとは別に、グルグル回る文字を表示して処理中であることを示す方法もあります。


今回は、後者のやり方です。


System.Consoleクラスには、カーソルの位置を制御するために以下のメソッド及びプロパティが存在します。

  • Console.SetCursorPositionメソッド
    • カーソル位置を設定します。
  • Console.CursorLeftプロパティ
    • バッファ領域のカーソルの列位置を取得します。
  • Console.CursorTopプロパティ
    • バッファ領域のカーソルの行位置を取得します。


要は、1文字描画して、その後カーソル位置を戻して再度描画すると
見た目グルグルしているように見えるという事になります。


以下サンプルです。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Gsf.Samples
{
    public class MainClass
    {
        static volatile bool _stop;

        static void Main()
        {
            Console.WriteLine("処理開始.....");

            //
            // 現在のカーソル位置を保持.
            //
            int left = Console.CursorLeft;
            int top  = Console.CursorTop;

            //
            // 処理中表示開始.
            //
            _stop =false;
            var task = Task.Factory.StartNew (() => 
                {
                    while (true)
                    {
                        if (_stop)
                        {
                            Console.SetCursorPosition(left, top);
                            Console.Write("");
                            break;
                        }

                        //
                        // カーソル位置を初期位置に戻しながら
                        // 各文字を表示していく.
                        //
                        Console.SetCursorPosition(left, top);
                        Console.Write("|");
                        Thread.Sleep(TimeSpan.FromSeconds(0.3));

                        Console.SetCursorPosition(left, top);
                        Console.Write("/");
                        Thread.Sleep(TimeSpan.FromSeconds(0.3));

                        Console.SetCursorPosition(left, top);
                        Console.Write("-");
                        Thread.Sleep(TimeSpan.FromSeconds(0.3));
                    }
                }
            );

            //
            // 時間がかかる処理をシミュレート.
            //
            Thread.Sleep(TimeSpan.FromSeconds(5.0));

            //
            // タスクを停止.
            //
            _stop = true;
            task.Wait();

            Console.WriteLine("終了");
        }
    }
}


上記のサンプルでは、メインスレッドを本処理として
コンソールに表示する処理は別スレッド扱いにしています。
実行すると、「処理開始....」と表示された行の下にグルグル回る文字が表示されます。


メインスレッド側でConsole.Writeとかしてしまうと画面に文字が混ざってしまうので
メイン側での出力はログファイルなどに出力しておきます。



================================
過去の記事については、以下のページからご参照下さい。