2017年1月12日木曜日

C#のConsoleにプログレスバー

C#のConsoleアプリで時間が掛かる処理を行う時にプログレスバーが欲しいので作ってみた。

static void SetProgress(int Value, int Max)
{
    Console.Write(Value + "/" + Max + " ");

    int w = Console.BufferWidth - Console.CursorLeft - 1;
    int p = ((Value * w) / Max);

    Console.Write("".PadRight(p, '*').PadRight(w, '-'));

    Console.CursorLeft = 0;
}

ControleのProgressBarと違ってMinimumは無いのでオフセットは各自で処理するように。
ループとかに入る前にはConsole.CursorVisibleにfalseを入れてカーソルを表示しないように、ループが終わったらtrueを入れてカーソルを表示するようにする。
プログレスバーを表示中には改行を行ってはならない。またSetProgressは改行を行わない。ループを抜けた時にはConsole.WriteLine();で改行すること。
プログレスバーの後ろに追加情報を表示する機能は実装していないが、プログレスバーの前に追加情報を表示することはできる。そういうことを行いたい場合はSetProgressを呼ぶ前にConsole.Writeを使って表示すること。重ねて言うが、Console.WriteLineを使ってはいけない。
ただしカーソル位置を呼び出し元で管理している場合は改行やカーソル位置の変更に制限はない。もっとも、プログレスバーの開始位置は任意なれど、終了位置は常に右端だから、コンソール内でGUIを作るにはあんまり向いてない。

当たり前だが、Paralell.Forとかの中で呼ぶとひどいことになる。シングルスレッドで使うことを前提としている。それからウインドウ幅(バッファ幅)が足りない場合の挙動とかは未確認。


たまに欲しい時にいちいちソースコード探すのが面倒なのでブログに貼り付けておく次第。

0 件のコメント:

コメントを投稿