Click here to Skip to main content
15,891,136 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
I've got a string array and I need to show the contents of it to a single label. It acts like a clock. The thing is I tried with everything I could but I failed. This is the code I've been trying. Its in VB.NET and there is a Thread.Sleep(2000) running to slow down the loop so I can display the contents in a label for 2 seconds. Is that the thing causing the problem? Please help.
Thanks.

VB
Dim j As Integer
For j = 0 To readText.Length
    label.text=readText(j)
    Thread.Sleep(2000)
Next


[Moved to question from an "answer" for OP]
Here is my code it's still not functioning:
VB
Imports System
Imports System.IO
Imports System.Threading

Public Class Form2
Dim readText() As String

Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load

    Dim path As String = "c:\test.txt"
    readText = File.ReadAllLines(path)

    Dim temp As String
    Dim i As Integer
    Dim rnum As Integer
    Dim r As New Random

    For Each text As String In readText
        rnum = r.Next(0, readText.Length)
        temp = readText(i)
        readText(i) = readText(rnum)
        readText(rnum) = temp
    Next text

    Dim j As Integer
    For j = 0 To readText.Length
        Label1.Text = readText(j)
        Thread.Sleep(2000)
    Next j

End Sub

End Class
Posted
Updated 12-Jan-11 23:48pm
v4
Comments
#realJSOP 12-Jan-11 9:37am    
Use Add a Comment link under the answer you want to respond to. If you don't do it that way, the person you're responding to won't get a notification that you responded.
Manfred Rudolf Bihy 13-Jan-11 5:49am    
Comment from ARopo: What is the problem now?

Use a BackgroundWorker object to control the display time, and use the Progress event to display the actual data based on the progress value you sentd to the event. The code below is in C#, but converting it to vb shouldn't be a problem.

C#
private void worker_DoWork(object sender)
{
    BackgroundWorker worker = sender as BackgroundWorker;
    int delay = 2000;
    int interval = 100;
    int elapsed = 0;
    int pos = myString.Length;

    while (!worker.CancellationPending)
    {
        if (eplapsed >= delay)
        {
            worker.ReportProgress(pos);  // change label text in the Progress event handler
            pos++;
            elapsed = 0;
            if (pos == myString.Length)
            {
                break;
            }
        }
        Thread.Sleep(interval);
    }
}

Caveat: I typed this without testing it so you may need to tweak it a little. This approach keeps your UI responsive to user input as well, and avoids using DoEvents().

 
Share this answer
 
v2
Comments
Manfred Rudolf Bihy 12-Jan-11 9:37am    
Good call! 5+
If you are new at vb.net All above are little bit complex. It would be very easy using a Timer. Threading or sleeping problems will never arise here.
How to do that:
1. Add a timer into your form.
2.Add into proc Form2_Load
VB
Timer1.Enabled = True
Timer1.Interval = 2000
Timer1.Tag=0

3. You set
VB
Dim readText() As String
as global. So no problem. Do not change it.
4. Now:
VB
Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    Try
        Label.Text = readText(Timer1.Tag)
        Timer1.Tag = Timer1.Tag + 1
    Catch ex As Exception
        Timer1.Tag = 0
        Label.Text = readText(Timer1.Tag)
        Timer1.Tag = Timer1.Tag + 1
    End Try
End Sub

Timer has a problem that is it 0~15ms tolerent. I don't know why. May be my pc is slow.
 
Share this answer
 
v2
Thread.Sleep(2000) is blocking your UI thread. While the loop is running the GUI will not respond. To manage long running methods you'll have to use a BackgroundWorker and update your GUI control (label in this case) from there. To be able to access the control from the BackgroundWorker you'll have to use Invoke();. See here: http://blogs.msdn.com/b/csharpfaq/archive/2004/03/17/91685.aspx[^].

Or just look at JSOP's answer. That's the way to do it!

Best Regards,
Manfred
 
Share this answer
 
v3
Comments
Espen Harlinn 13-Jan-11 8:43am    
5+ takes care of the most important issue
Manfred Rudolf Bihy 13-Jan-11 8:46am    
Thanks Espen!
To see your label update every 2 seconds you need to process events try something like this:

VB
Dim j As Integer
       For j = 0 To readText.Length
           label.text=readText(j)
           Application.DoEvents()
           Thread.Sleep(2000)
       Next


Detail.

The user interface is updated via events/messages. These events/messages are queued and the processed by the main user interface thread. When you update a label it is usually on the main user interface thread, otherwise you have to update it indirectly with Invoke().

Thread.Sleep(2000) puts the current thread (in this case the main user interface thread) to sleep for 2000 milliseconds. during this time no messages/events can be processed Application.DoEvents() forces all pending messages/events to be processed.


Any thing you do on an event will holdup the message/event processing until you finish unless you start off a new thread or force processing with DoEvents
 
Share this answer
 
v2
Comments
Manfred Rudolf Bihy 12-Jan-11 9:33am    
Have my 5+. Eventhough I still think DoEvents is evil. But WTH it is VB.NET :)
Manfred Rudolf Bihy 12-Jan-11 9:34am    
[Moved from answer for OP]
I'm sorry, can you please elaborate a little bit?? I'm a newbie!!
Manfred Rudolf Bihy 12-Jan-11 9:37am    
[Moved from answer for OP]

erik & aropo, it still is not working. still throws an exception. it says IndexOutofRrangeException in the line label.text=readText(j)
ARopo 12-Jan-11 9:47am    
Your must be indexing out of the range of the array. not a vb expert if the array range is either 0 to readText.Length-1 or 1 to readText.Length
ARopo 12-Jan-11 9:51am    
Find out what the value of j is when this exception is thrown
Put this just before the Thread.Sleep line:

Application.DoEvents()


This will refresh your label before sending the GUI thread to sleep.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900