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);

或者实现WHITE TO RED闪烁

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

很抱歉这么说,但闪烁文本可能不是使用控制台应用程序做的明智之举。

控制台不支持您,因此您必须自己实现它。由于控制台只会写入光标所在的位置,因此您必须不断将光标移回警报的开头!写下你想要的,然后把它移回原来的位置。这不会很漂亮。

如果您确实想这样做,最好的方法是使用计时器(System.Threading.Timer)。计时器将允许应用程序的其余部分在更改闪烁文本之间运行。当计时器事件发生时,您需要保存光标位置,移动到警报文本,写入或空白,然后将光标设置回保存的位置。当你这样做的时候,你需要找到一些方法来阻止文件写入,这样你就不会在“警告!警告!警告!”的地方写入文件块。应该。

最后应该注意的是,对于决定将应用程序的输出通过管道传输到如下文件的任何人来说,这种技术将会非常陌生: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 回答
-3

最简单但最麻烦的方法是:

static void Blink()
{
    Console.Clear();
        string name = "Your Text";
        Console.WriteLine(name);
        Thread.Sleep(500); //Break
        Console.Clear();
        Thread.Sleep(500);
        Console.WriteLine(name);
        Thread.Sleep(500);
        Console.Clear();
        Thread.Sleep(500);
        Console.WriteLine(name);
        Thread.Sleep(500);
        Console.Clear();
        Thread.Sleep(500);
        Console.WriteLine(name);
        Thread.Sleep(500);
        Console.Clear();
        Thread.Sleep(500);
        Console.WriteLine(name);
        Thread.Sleep(500);
        Console.ReadKey();
}
于 2017-04-16T20:11:11.663 回答