Нить спать в цикле - PullRequest
       9

Нить спать в цикле

1 голос
/ 03 февраля 2009

Мне нужна ваша помощь для использования этого метода:

for (int i =0; i<dt.count; i++)
{
    process...
    sleep(3000);
}

int sleeptime=0;
private void timer2_Tick(object sender, EventArgs e)
{
    for (int i = 0; i &#60; mylist.Items.Count;)
    {
        listBox1.Items.Add(mylist.Items[i].Name.ToString() + "starting...");
        sleeptime = int.Parse(mylist.Items[i++].TimeSpan.ToString()) - timer2.Interval;
        System.Threading.Thread.Sleep(sleeptime);
    }
    timer1.Start();
    timer2.Stop();
}

Но я не вижу своего потока данных, как водопад.

Ответы [ 2 ]

13 голосов
/ 03 февраля 2009

Вы блокируете поток пользовательского интерфейса - обновления обычно не отображаются, пока вы не покинете обработчик событий. Хакерский подход заключается в использовании Application.DoEvents(), но это ленивый и риск повторного входа особенно , если вы делаете паузу.

Лучший подход - выполнить работу в фоновом потоке и использовать Invoke для передачи данных в пользовательский интерфейс (не связываться с пользовательским интерфейсом из рабочего потока).

Или просто добавить отдельные элементы в отдельные галочки?

Вот пример использования BackgroundWorker для работы, использования ReportProgress для помещения элементов в пользовательский интерфейс:

using System.ComponentModel;
using System.Threading;
using System.Windows.Forms;
static class Program
{
    static void Main()
    {
        // setup some form state
        Form form = new Form();
        ListView list = new ListView();
        list.View = View.List;
        BackgroundWorker worker = new BackgroundWorker();
        worker.WorkerReportsProgress = true;
        form.Controls.Add(list);
        list.Dock = DockStyle.Fill;
        // start the worker when the form loads
        form.Load += delegate {
            worker.RunWorkerAsync();
        };
        worker.DoWork += delegate
        {
            // this code happens on a background thread, so doesn't
            // block the UI while running - but shouldn't talk
            // directly to any controls
            for(int i = 0 ; i < 500 ; i++) {
                worker.ReportProgress(0, "Item " + i);
                Thread.Sleep(150);
            }
        };
        worker.ProgressChanged += delegate(object sender,
           ProgressChangedEventArgs args)
        {
            // this is invoked on the UI thread when we
            // call "ReportProgress" - allowing us to talk
            // to controls; we've passed the new info in
            // args.UserState
            list.Items.Add((string)args.UserState);
        };
        Application.Run(form);
    }
}
0 голосов
/ 07 февраля 2010

Или вы можете использовать вместо этого класс System.Threading.Timer. Обратный вызов таймера выполняется в потоке из ThreadPool, а не в потоке пользовательского интерфейса. Но, кроме того, вы не можете получить прямой доступ к любым элементам управления графическим интерфейсом, поэтому вам придется использовать Invoke.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...