7

私はC#の初心者です

私はこのコードを持っています

    FileStream D = new FileStream("C:/PersonalAssistant/RecentMeetingDetails.txt", FileMode.Open, FileAccess.Read);
    StreamReader DR = new StreamReader(D);
    DR.BaseStream.Seek(0, SeekOrigin.Begin);

    Console.ForegroundColor = ConsoleColor.Red;
    Console.WriteLine("ALERT! ALERT!! ALERT!!!");
    Console.WriteLine("\nYour Closest Appointment is on " + rd + " and has the following info");

    string data = DR.ReadLine();
    while (data != null)
    {
         Console.WriteLine(data);
         data = DR.ReadLine();
    }
    D.Close();
    DR.Close();

このコードが欲しい

    Console.WriteLine("ALERT! ALERT!! ALERT!!!");

他の詳細がファイルから読み取られて画面に表示されている間、点滅します

私はこれを試しました

   private static void WriteBlinkingText(string text, int delay)
   {
        bool visible = true;
        while (true)
        {
            Console.Write("\r" + (visible ? text : new String(' ', text.Length)));
            System.Threading.Thread.Sleep(delay);
            visible = !visible;
        }
   } 

そして、console.writeline を次のように変更します。

    WriteBlinkingText("ALERT! ALERT!! ALERT!!!",500);

それは機能しましたが、他の詳細は表示されませんでした...

このコードを修正するのを手伝ってください

4

5 に答える 5

4

根本的な原因:

  • 実際には、すべてを単一の で処理していますThread
  • スレッドは無限ループ、つまりメソッドwhile(true) {... }内でブロックされます。WriteBlinkingText()

解決策:

点滅するテキストを処理するための別のスレッドを作成します。Main Thread残りのコード実行を続行します。

于 2013-06-11T10:11:55.003 に答える
3

私はあなたがこれを探していると思います:

bool visible = true;
do
{
    //Press Ctrl + C to Quit
    string alert = visible ? "ALERT! ALERT!! ALERT!!!" : "";
    visible = !visible;
    Console.Clear();
    string details = File.ReadAllText(@"C:\PersonalAssistant\RecentMeetingDetails.txt");
    Console.Write("{0}\n{1}", alert, details);
    Thread.Sleep(100);
} while (true);

または、白からへの点滅を実現するには

bool visible = true;
do
{
    //Press Ctrl + C to Quit
    string alert = "ALERT! ALERT!! ALERT!!!";
    Console.ForegroundColor = visible ? ConsoleColor.Red : ConsoleColor.White;
    visible = !visible;
    Console.Clear();
    string details = @"C:\PersonalAssistant\RecentMeetingDetails.txt";
    Console.WriteLine(alert);
    Console.ForegroundColor = ConsoleColor.White;
    Console.WriteLine(details);
    Thread.Sleep(100);
} while (true);

これをメソッドに簡単にリファクタリングできます。

private static void Blinker(string text, int milliseconds)
{
    bool visible = true;
    while(true)
    {
        //Press Ctrl + C to Quit
        string alert = visible ? "ALERT! ALERT!! ALERT!!!" : "";
        visible = !visible;
        Console.Clear();
        string details = File.ReadAllText(@"C:\PersonalAssistant\RecentMeetingDetails.txt");
        Console.Write("{0}\n{1}", alert, details);
        Thread.Sleep(milliseconds);
    }
}
于 2013-06-11T10:51:32.957 に答える
2

申し訳ありませんが、コンソール アプリケーションでテキストの点滅を行うのは賢明なことではありません。

コンソールはこれをサポートしていないため、自分で実装する必要があります。コンソールはカーソルがある場所にしか書き込みを行わないため、カーソルを Alert! の開始点まで戻し続ける必要があります。必要なものを書き留めてから、元の場所に戻します。これはきれいにはなりません。

これを行うには、タイマー (System.Threading.Timer) を使用するのが最善の方法です。タイマーは、点滅するテキストへの変更の間にアプリケーションの残りの部分を実行できるようにします。タイマー イベントが発生したら、カーソル位置を保存し、アラート テキストに移動して書き込みまたは空白にしてから、カーソルを保存した位置に戻す必要があります。これを行っている間、ファイルの書き込みをブロックする方法を見つける必要があります。これにより、「Alert! Alert! Alert!」という場所にファイルのチャンクが書き込まれることはありません。する必要があります。

最後に、アプリケーションの出力を C:>MyApplication.exe > output.txt のようなファイルにパイプすることを決定した人にとって、この手法は非常に奇妙であることに注意してください。

このようなものはそれを行うべきです:

class Program
{
  static System.Threading.Timer timer = new Timer(TimerCallback, null, System.Threading.Timeout.Infinite, 0);
  static int alertX;
  static int alertY;
  static bool alertDisplayed = false;
  static int cursorX;
  static int cursorY;
  static object consoleLock = new object();

  static void Main(string[] args)
  {
     FileStream D = new FileStream("C:/PersonalAssistant/RecentMeetingDetails.txt", FileMode.Open, FileAccess.Read);
     StreamReader DR = new StreamReader(D);
     DR.BaseStream.Seek(0, SeekOrigin.Begin);

     Console.ForegroundColor = ConsoleColor.Red;
     WriteFlashingText();
     lock (consoleLock)
     {
        Console.WriteLine("\nYour Closest Appointment is on " + rd + " and has the following info");
     }

     string data = DR.ReadLine();
     while (data != null)
     {
        lock (consoleLock)
        {
           Console.WriteLine(data);
        }
        data = DR.ReadLine();
     }
     D.Close();
     DR.Close();
  }

  static void WriteFlashingText()
  {
     alertX = Console.CursorLeft;
     alertY = Console.CursorTop;
     timer.Change(0, 200);
  }

  static void TimerCallback(object state)
  {
     lock (consoleLock)
     {
        cursorX = Console.CursorLeft;
        cursorY = Console.CursorTop;

        Console.CursorLeft = alertX;
        Console.CursorTop = alertY;

        if (alertDisplayed)
        {
           Console.WriteLine("Alert! Alert! Alert!");
        }
        else
        {
           Console.WriteLine("                    ");
        }
        alertDisplayed = !alertDisplayed;

        Console.CursorLeft = cursorX;
        Console.CursorTop = cursorY;
     }
  }
}
于 2013-06-11T10:19:30.357 に答える
0
class Program {
    static void Main(string[] args) {
        blinkText t = new blinkText("TestTestTest", 500); //new blinkText object
        t.start(); //start blinking

        Thread.Sleep(5000); //Do your work here

        t.stop(); //When your work is finished, call stop() to stop the blinking text blinking

        Console.ReadKey();
    }
}

public class blinkText {
    public blinkText(string text, int delay) {
        this.text = text;
        this.delay = delay;
        this.startLine = Console.CursorTop; //line number of the begin of the text
        this.startColumn = Console.CursorLeft; //column number of the begin of the text
        Console.Write(this.text);
        visible = true;
    }
    public string text;
    public int delay;
    int startLine;
    int startColumn;

    bool visible;

    Timer t;

    public void start() {
        t = new Timer(delegate { //Timer to do work async
            int oldCursorX = Console.CursorLeft; //Save cursor position
            int oldCursorY = Console.CursorTop;  //to restore them later
            Console.CursorLeft = startLine; //change cursor position to
            Console.CursorTop = startColumn; //the begin of the text
            visible = !visible;
            if (visible) {
                Console.Write(text); //write text (overwrites the whitespaces)
            } else {
                ConsoleColor oldColor = Console.ForegroundColor; //change fore color to back color
                Console.ForegroundColor = Console.BackgroundColor; //(makes text invisible)
                Console.Write(text); //write invisible text(overwrites visible text)
                Console.ForegroundColor = oldColor; //restore the old color(makes text visible)
            }
            Console.CursorLeft = oldCursorX; //restore cursor position
            Console.CursorTop = oldCursorY;
        });
        t.Change(0, this.delay); //start timer
    }

    public void stop() {
        t.Change(0, -1); //stop timer
        int oldCursorX = Console.CursorLeft;
        int oldCursorY = Console.CursorTop;
        Console.CursorLeft = startLine;
        Console.CursorTop = startColumn;
        Console.Write(text); //display text visible
        Console.CursorLeft = oldCursorX;
        Console.CursorTop = oldCursorY;
        visible = true;
    }
}

答えを編集しました。ここで、非同期タイマーを呼び出してテキストを点滅させるクラスを作成しました。したがって、これはあなたのプログラムをブロックしません。これを示すためThread.Sleep(5000)に、テキストが点滅し始めた後に を作成しました。これは、完了するまでに時間がかかるコードである可能性があります。その後、テキストの点滅が終了します。

于 2013-06-11T10:14:56.843 に答える