2016-07-22 2 views
0

Я хочу прочитать одну строку и поместить ее в текстовое поле через каждые 1 секунду. Мне удалось этот код:Таймер и цикл while

private void button1_Click(object sender, EventArgs e) 
{ 
    while ((line = file.ReadLine()) != null) 
    { 
     timer.Start(); 
    } 
} 

private void timer1_Tick(object sender, EventArgs e) 
{ 
    textBox1.text += line + "\r\n"; 
} 

Но line не доступна. Я также пробовал что-то вроде этого:

private void button1_Click(object sender, EventArgs e) 
{ 
    timer.Start(); 
} 


private void timer1_Tick(object sender, EventArgs e) 
{ 

    while ((line = file.ReadLine()) != null) 
    { 
     textBox1.Text += line + "\r\n"; 
    } 

} 

Но он игнорирует интервал таймера. Более того, я не знаю, как я могу остановить таймер в обоих примерах. Можете ли вы дать мне совет, что я могу сделать с этим?

Редактировать

Любые идеи, почему этот код хорошо работает с if, но не с while?

private void timer1_Tick(object sender, EventArgs e) 
     { 

      while ((line1 = file1.ReadLine()) != null) 
      { 


       while ((line2 = file2.ReadLine()) != null) 
       { 

        try 
        { 
          //some code 
        } 

        catch 
        { 

          //some code 
        } 

        finally 
        { 
          //some code 

        } 

       } 



      } 

       timer1.Stop(); 


     } 

Я хочу объединить все строки из file2 с каждой строкой из file1.

+0

Первый пример будет делать странные вещи, Второй пример очень неясно, так как мы не знаем, как таймер инициализируется – lokusking

+1

Подсказка: сделайте его глобальным и в timer1_Tick(), прочитайте следующую строку, отобразите его и запустите свой таймер. –

+0

Первый блок кода говорит «для каждой строки в файле, запустите таймер». Я думаю, что это может быть частью вашей проблемы. Если вы поместите 'timer.Start' после блока while, вы можете получить немного дальше. Я также не знаю, что вы подразумеваете под «Но« строка »недоступна». Вы имеете в виду, что текст не отображается в текстовом поле, но вы ожидаете? Вы также не добавляете ни одну из этих строк в текстовое поле внутри этого цикла, поэтому весь файл (за исключением последней «строки», который будет иметь значение null) считывается и отбрасывается прежде, чем что-либо еще произойдет. –

ответ

2

Этот код берет строку из данного файла (в настоящее время c: \ myfile \ test.xml) и считывает его в массив, а затем запускает таймер. Как только таймер будет запущен, он определит, был ли завершен конец ваших данных. Если все еще остались данные, вы добавите их в текстовое поле. Если данные не оставлены, таймер остановится. Вы можете снова нажать кнопку, чтобы снова перезапустить процесс.

//holds each line of the file contents 
    string[] lines = null; 
    //sets the current line number that you are at in the lines array 
    int curline = 0; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     //reads all lines of files and starts the timer 
     lines = File.ReadAllLines(@"C:\myfile\test.xml"); 
     curline = 0; 
     timer1.Start(); 
    } 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     //if not end of data then insert on another line of the textbox 
     if (curline < lines.Length) 
     { 
      textBox1.Text += lines[curline] + "\r\n"; 
      curline++; 
     } 
     else 
     { 
      //else stop the timer 
      timer1.Stop(); 
     } 
    } 

Счастливый Coding, Джейсон

+0

+1 для правильного определения переменных. Я бы предложил использовать очередь для строк, а не строковый массив, и каждый раз потянув линию на timer1_Tick с lines.Dequeue(), а не на поле curline. Тем не менее, ваш подход отлично работает. –

+0

@audiophonic Вы должны опубликовать это как новый вопрос. – MickyD

1

Во втором примере изменить код на следующие

private void timer1_Tick(object sender, EventArgs e) { 
    if((line = file.ReadLine()) != null) 
    { textBox1.Text += line + "\r\n"; 
    } 
    else 
    { 
    //Stop Timer here 
    } 
} 
+1

Единственная проблема заключается в том, что вы оставили блокировку объекта «файл» в открывшемся файле после того, как вы закончили его обработку. Вероятно, это больше, чем это упражнение. –

0

Мой лучший вариант: (предполагает MyFilePath содержит путь к файлу, который вы используете)

 private Queue<string> _lines; 

    private void button1_Click(object sender, EventArgs e) 
    { 
     _lines = new Queue<string>(System.IO.File.ReadAllLines(myFilePath)); 
     textBox1.Text = string.Empty; 
     timer1.Start(); 
    } 

    private void timer1_Tick(object sender, EventArgs e) 
    { 
     if (_lines.Any()) 
      textBox1.Text += _lines.Dequeue() + Environment.NewLine; 
     else 
      timer1.Stop(); 
    } 
1

Адрес:

Как уже упоминалось в комментариях, начните все в начале и в фоновом режиме. Сначала прочитайте свой файл и подготовьте контейнер ваших линий. Затем запустите таймер. Теперь каждый раз, когда timer1.Ticks, мы будем отображать строку из нашего контейнера, начиная с первой строки. Мы продолжаем делать этот процесс снова и снова.

Остерегайтесь пути к файлу.

MyFile: "C:\Users\Public\TestFolder\Test.txt"

б

с

д

Ē

е

код готов к компиляции:

using System; 
using System.Linq; 
using System.Windows.Forms; 

namespace WindowsFormsApplication1 
{ 
    public partial class ExampleProgram : Form 
    { 
     // global variables 
     string[] MyLines = System.IO.File.ReadAllLines(@"C:\Users\Public\TestFolder\Test.txt"); // contain all lines 
     int MyCurrentLine = 0; 

     public ExampleProgram() 
     { 
      InitializeComponent(); 
      StartProgram(); // start the program 
     } 

     private void StartProgram() 
     { 
      timer1.Interval = 1000; // set interval in milliseconds 
      timer1.Start(); // start timer 
     } 

     private void timer1_Tick(object sender, EventArgs e) 
     { 
      //timer1.Stop(); // first thing first - Edit: Looks like you did not need this. 
      textBox1.Text = MyLines[MyCurrentLine % MyLines.Count()]; // display next line 
      ++MyCurrentLine; // increment counter 
      //timer1.Start(); // restart - Edit: And also won't need this. Less code.. Nice ! 
     } 
    } 
} 

Результат:

enter image description here

+0

Зачем останавливать/запускать таймер в 'timer1_Tick'? Это не так, как если бы обратный вызов длился долгое время – MickyD

+0

@MickyD Я не уверен, но профессор, который научил меня этому, сказал мне сделать это. Может быть, я должен удалить его тогда :) Спасибо за указание, что вне –

+0

Все хорошо. Хорошая анимация тоже, кстати, больше SO-ответов должно это сделать :) – MickyD