2013-06-17 3 views
1

Мне нужно запустить бесконечный цикл while, когда приложение формы запускается. Форма начинается как этотБесконечный цикл while с использованием формы C#

public Form1() 
{ 
     InitializeComponent(); 
} 

Теперь я хочу, чтобы запустить другую функцию, которая будет иметь бесконечный цикл внутри с одной второй раз во сне.

public void doProcess(){ 

    while(true){ 
     Thread.Sleep(1000); 
     // other task 
    } 
} 

Как это сделать? Когда я вызываю doProcess() в конструкторе, он не отображает форму. Я попытался запустить цикл while для 10 итераций. Форма появилась только после всех итераций. Я не понимаю, почему это происходит.

+0

Где вы вызываете метод doProcess? До или после InitializeComponent? И вы пробовали событие form_load? – Martijn

+1

Ps, use pascal корпус «DoProcess» –

+1

Я не понял, что именно вы хотите сделать. Я имею в виду, если вы используете бесконечный цикл, который имеет Thread.Sleep (1000) (в течение 1 секунды), поэтому он не будет показать форму, поскольку она бесконечно захватывает разрыв, и если вы ставите ее на 10 итераций, то, очевидно, она будет показана после 10 итераций. Так что, пожалуйста, не стесняйтесь пояснить вопрос. :) –

ответ

4

Вы можете начать новая нить вроде этого:

new Thread(() => 
{ 
    while (true) 
    { 
     Thread.Sleep(1000); 

     //other tasks 
    } 
}).Start(); 

Хотя я предлагаю вам прочитать прошивку, прежде чем вы это сделаете. Если вы хотите обновить форму из другого потока, вы должны использовать: Form.Invoke().

Например: w является формой

w.Invoke((MethodInvoker) delegate 
{ 
    w.Width += 100; 
}); 
2

Это происходит потому, что ctor никогда не выходит и поэтому форма не может быть показана - разве это не очевидно?

Если вы хотите запустить линию forever/sleep loop, вы должны отключить ее.

Не ждите в обработчиках событий GUI (или ctors).

Можете ли вы использовать формы. Timer?

3

Короче говоря, вы блокируете поток пользовательского интерфейса с помощью этого бесконечного цикла.

запустить его async:

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 

     BeginWork(); 
    } 

    private async void BeginWork() 
    { 
     while (true) 
     { 
      // Since we asynchronously wait, the UI thread is not blocked by the file download. 
      var result = await DoWork(formTextField.Text); 

      // Since we resume on the UI context, we can directly access UI elements. 
      formTextField.Text = result; 
     } 
    } 

    private async Task<string> DoWork(object text) 
    { 
     // Do actual work 
     await Task.Delay(1000); 
     // Return Actual Result 
     return DateTime.Now.Ticks.ToString(); 
    } 
} 

Через некоторое время (истина), может быть немного чрезмерным для цикла обновления. Могу ли я рекомендовать потенциально использовать таймер и/или использовать токены отмены, чтобы с нетерпением отменить запросы, которые потребовались для того, чтобы не обновлять пользовательский интерфейс с потенциально устаревшими результатами в сценариях с высокой производительностью.

E.g.

public partial class Form1 : Form 
{ 
    private readonly Timer _sampleTimer; 

    public Form1() 
    { 
     InitializeComponent(); 

     _sampleTimer = new Timer 
      { 
       Interval = 500 // 0.5 Seconds 
      }; 
     _sampleTimer.Tick += DoWorkAndUpdateUIAsync; 
    } 

    private async void DoWorkAndUpdateUIAsync(object sender, EventArgs e) 
    { 
     // Since we asynchronously wait, the UI thread is not blocked by "the work". 
     var result = await DoWorkAsync(); 

     // Since we resume on the UI context, we can directly access UI elements. 
     resultTextField.Text = result; 
    } 

    private async Task<string> DoWorkAsync() 
    { 
     await Task.Delay(1000); // Do actual work sampling usb async (not blocking ui) 
     return DateTime.Now.Ticks.ToString(); // Sample Result 
    } 

    private void startButton_Click(object sender, EventArgs e) 
    { 
     _sampleTimer.Start(); 
    } 

    private void stopButton_Click(object sender, EventArgs e) 
    { 
     _sampleTimer.Stop(); 
    } 
} 
+0

чистый и эффективный! –

1

Вы блокируете поток пользовательского интерфейса. Следовательно, пользовательский интерфейс не может быть обработан, пока выполняется doProcess.

При использовании .Net 4.5, вы можете использовать асинхронное ожидания:

public async void doProcess(){ 
    while(true){ 
     await Task.Delay(1000); 
     // other task 
    } 
} 

уборщик решение было бы использовать таймер, который активирует событие 1 раз в секунду. Вы можете отключить таймер после 10 циклов.

+0

Вы имеете в виду 'await Task.Delay (1000);' –

0

Вы не вышли из конструктора, чтобы форма не отображалась. Если вы хотите сделать это после того, как форма покажет место вашего кода в событии Form_Load. Но же вы хотите сделать это с помощью фонового потока, так что вы можете использовать BackgroundWorker

0

Вы можете поместить его после того, как компонент Initialize, или найти событие загрузки формы и вставьте код туда

Смежные вопросы