开发者

Need a timer that updates after each finish item in a Listbox

right now i have implemented a timer class like this.

    static void DelaySec(string delayName)
    {
        switch (delayName)
        {
            case "Delay1":
                System.Threading.Thread.Sleep(1000);
                break;
            case "Delay2":
                System.Threading.Thread.Sleep(2000);
                break;
            case "Delay3":
                System.Threading.Thread.Sleep(3000);
                break;
            case "Delay4":
                S开发者_StackOverflowystem.Threading.Thread.Sleep(4000);
                break;
            case "Delay5":
                System.Threading.Thread.Sleep(5000); 
                break;
            default:
                break;
        }
    }

i would like to set a delay and not a sleep between items in a listbox so my UI dont freeze.

hope someone out there who can help me.


If you're doing a significant amount of work - or even simulating it - you should not be doing it on the UI thread. That's why your UI thread is freezing.

You should be doing it on a background thread, and using Control.Invoke/BeginInvoke or possibly BackgroundWorker to marshal any UI updates (e.g. changing a progress bar) back to the UI thread.

It's unclear what your timer is really meant to be doing here, but when you've worked out how to offload the work to a different thread, then describe what your code looks like.

Note that you could use System.Windows.Forms.Timer to interact easily with the UI thread - but it should still be event-based, rather than you running a lot of work in the UI thread. So for example, you could create a "queue" of work to do (based on the listbox item), set up a timer to fire every second, and on each timer tick perform the work - if it's short - for that one item. Between calls, the UI thread will be free to update itself.

Note that the async feature of C# 5 will mean you will be able to write normal sequential code like this, but that's a way off yet.


    ...
    stopwatch.Start();
    timerLabel.Visible = true;
    progressBar1.Maximum = SequenceListBox.Items.Count;
    progressBar1.Step = (progressBar1.Maximum / SequenceListBox.Items.Count);
    progressBar1.PerformStep();
    foreach(ElementControl item in SequenceListBox.Items)
    {
        item.RunElement();
        Application.DoEvents();
    }
    stopwatch.Stop();
    ...


I think this is what you want to achieve. However, I am not sure whether when the stopwatch to start and stop timing. Your example seems to be start the watch multiple times and stop it only once.

    private int currItem;
    private List<ElementControl> Elements = new List<ElementControl>();
    private void StartButton_Click(object sender, EventArgs e)
    {            
        if (SequenceListBox.Items.Count <= 0)
        {
            MessageBox.Show("Please select an Item");
            return;
        }

        // Prevent starting again
        StartButton.Enabled = false;

        Elements.Clear();
        foreach (ElementControl ele in SequenceListBox.Items)
            Elements.Add(ele);

        // Must start stopwatch before timer to prevent timer_Elapsed from closing a non-existent stopwatch
        stopwatch = Stopwatch.StartNew();
        stopwatch.Start();

        // Start timer
        System.Timers.Timer timer = new System.Timers.Timer(1000);
        timer.AutoReset = true;
        timer.Elapsed += new System.Timers.ElapsedEventHandler(timer_Elapsed);
        timer.Start();
    }

    public delegate void ReportProgressHandler(int value, string text);
    private void ReportProgress(int value, string text)
    {
        if (InvokeRequired)
            Invoke(new ReportProgressHandler(ReportProgress), value, text);
        else
        {
            if(value <= progressBar1.Maximum)
                progressBar1.Value = value;
            timerLabel.Text = text;
        }
    }
    private void timer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        // If all item process, stop timer, stopwatch and re-enable button
        if (currItem >= Elements.Count)
        {
            timer.Stop();
            stopwatch.Stop();
            ReportProgress (curItem, stopwatch.Elapsed.TotalSeconds.ToString("0" + " sec"));
            stopwatch = null;
            MessageBox.Show("The Test is Finish");
            //StartButton.Enabled = true;
            // Use the same approach as that used to report progress.
        }
        else
        {
            // Select item and run it
            ElementControl item = Elements[curItem];
            item.RunElement();
            currItem++;

            ReportProgress (curItem, "sometext"));
        }
    }

this is another possible way to do it:

    class Task
    {
        public List<ElementControl> Elements = new List<ElementControl>();
    }
    private void buttonStart_Click(object sender, EventArgs e)
    {
        buttonStart.Enabled = false;

        Task task = new Task();
        foreach (ElementControl ele in SequenceListBox.Items)
            task.Elements.Add(ele);

        progressBar1.Maximum = task.Elements.Count;
        backgroundWorker1.RunWorkerAsync(task);
    }
    public delegate void ReportProgressHandler(int value, string text);
    private void ReportProgress(int value, string text)
    {
        if (InvokeRequired)
            Invoke(new ReportProgressHandler(ReportProgress), value, text);
        else
        {
            if(value <= progressBar1.Maximum)
                progressBar1.Value = value;
            label1.Text = text;
        }
    }
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        Task task = e.Argument as Task;
        if (task != null)
        {
            int i = 0;
            foreach (ElementControl ele in task.Elements)
            {
                i++;
                ele.RunElement();
                ReportProgress(i, "sometext + " + i.ToString());
                System.Threading.Thread.Sleep(1000);
            }
            MessageBox.Show("Completed!");
        }
    }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜