views:

837

answers:

2

I need your help for using this method:

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

But I don't see my data flow like waterfall.

+10  A: 

You are blocking the UI thread - no updates will usually show until you leave the event-handler. A hacky approach is to use Application.DoEvents(), but this is lazy and risks re-entrancy especially if you are pausing.

A better approach is to do the work on a background thread, and use Invoke to push the data to the UI (don't talk to the UI from the worker thread).

Or just add individual items in separate ticks?

Here's an example using BackgroundWorker for the work, using ReportProgress to push items onto the UI:

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);
    }
}
Marc Gravell
A: 

Or you can use instead System.Threading.Timer class. The timer's callback is executed on a thread from ThreadPool, not the UI thread. But than, you can't directly access any GUI controls, so you would have to use Invoke.

Igor