Click here to Skip to main content
15,900,906 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi everybody!
I'm a new member here and ofcourse, I'm a newbie of VB.NET, too.

Well, I am not an English or American..., so I am not good at English, sorry about that.
But I really need help in this situation. I created an VB application by Visual Studio 2008. It called "Random Number".

I want to make that application because I have a girl shoes shop, so I want to make a program show Random product with its price in my computer. That "random number" application is my small first test before I can do that program.

Let's begin my problem, hihi.

Well, this is my application graphic:


<img src="http://i375.photobucket.com/albums/oo199/congchuatimhoangtu1989/random1.jpg">

As you can see, my application has 4 main parts:
- Lower number (txtLower): This is where I put the Lowest number.
- Higher number (txtHigher): This is where I put the Highest number.
- Button Random Begin (btRandom): button to activate the program.
- Lable Ramdom (lbRandom): this is where the "random number" between Lower and Higher number show up.

I want an application where I can put Lowest and Highest number and then the program will show the random number between them automatically.

So, I make I loop test like this code:

VB
Private Sub btRandom_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btRandom.Click

        Dim lower, higher, i As Integer
        Dim R As New Random
        lower = txtLower.Text
        higher = txtHigher.Text


        For i = 1 To 10
            lbRandom.Text = R.Next(lower, higher)
            Threading.Thread.Sleep(500)
        Next

End Sub


So, as my test code, it means after each 0,5 second, one random number will show up.
But, the problem is it was not. In fact, It wait for the loop end, it show. Means after 5 seconds (cause i use loop from 1 to 10, each time 500 ms), just 1 random number show.
It is not what I want.

As SAKryukov, I should not use Threading.Thread.Sleep and Appilcation.DoEvent. But I'm just a newbie of VB, so if you don't mind, please show me an example of another solutions. Thank you.

So, if you have time, can you please help me to know how to solve that problem.
Thank you so much!
Posted
Updated 2-Jan-12 17:16pm
v2
Comments
Sergey Alexandrovich Kryukov 3-Jan-12 0:26am    
No, you should Threading.Thread.Sleep if you need, but in another thread, not in UI thread.
Is it System.Windows.Forms or not?
--SA
Tin Christina 3-Jan-12 1:08am    
yes, it just a form
Sergey Alexandrovich Kryukov 3-Jan-12 0:31am    
By the way, if you are newbie in VB.NET, why learning this language, which is not standard (unlike C# and C++/CLI strictly standardized under ECMA and even ISO), and, frankly, viewed as non-professional by many who don't take it seriously (I don't want to discuss if the language is good or not; it's pretty good)? This is just a fact of life; if you are looking for help or .NET code, most of it will be in C#, no matter if we like it or not.

Even with Microsoft, C# is thoroughly innovated, VB.NET always go behind.

Not to worry though; you can live with VB.NET as well, just with some more problems.
--SA
Tin Christina 3-Jan-12 1:09am    
thank for that suggestion. I use VB just because I buy a VS 2008 disc and I see it in first line of new project menu, hihi. So I started learning VB few days ago...

This is a code sample created on OP's request:



First, let's make a thread wrapper. Later on, you can add some random algorithm, input numeric ranges in it. For now, it's important to make a skeleton: generate some number and fire an event with new value; also, it can be started/paused/resumed/aborted. The thread itself is hidden for a user. Note the use of event handle — this is the way to use long-living thread and keep it in a wait state without wasting any CPU time. On a wait of the handle, a thread is switched out and never scheduled back to execution until waken up by the call to ManualResetEvent.Set, timeout or Abort called in any other thread.

The thread is abstracted from the UI. It's responsibility of the UI thread to add an event handle to the invocation list of event NumberGenerated.

[EDIT]

The thread wrapper is very important to avoid parametrized thread start and for better encapsulation in general.

Please see my past answers for more detail:
How to pass ref parameter to the thread[^],
change paramters of thread (producer) after it started[^].

This is a VB.NET translation:
Passing arguments to a threaded LongRunningProcess[^].

VSNetVbHarry was so nice to do this work.

[END EDIT]

C#
namespace RandomTest {
    using System.Threading;
    
    internal class ThreadWrapper {

        internal class NumberGeneratedEventArgs : System.EventArgs {
            internal NumberGeneratedEventArgs(int number) { this.fNumber = number; }
            internal int Number { get { return fNumber; } }
            int fNumber;
        } //class NumberGeneratedEventArgs
        
        internal ThreadWrapper(int sleepTime) {
            this.thread = new Thread(this.Body);
            this.sleepTime = sleepTime;
        } //ThreadWrapper

        internal void Start() { this.thread.Start(); }
        internal void Abort() { this.thread.Abort(); }
        internal void Pause() { this.waitHandle.Reset(); }
        internal void Resume() { this.waitHandle.Set(); }

        internal event System.EventHandler<NumberGeneratedEventArgs>
            NumberGenerated;

        void Body() {
            int value = 0;
            while (true) {
                waitHandle.WaitOne();
                if (NumberGenerated != null)
                    NumberGenerated.Invoke(this, new NumberGeneratedEventArgs(value));
                value++;
                Thread.Sleep(sleepTime);
            } //loop
        } //Body
        
        Thread thread;
        int sleepTime;
        ManualResetEvent waitHandle = new ManualResetEvent(false); //non-signalled
    
    } //ThreadWrapper

} //namespace RandomTest


Now, let's use it in the form. I intentionally made it all in one file and avoided use of Designer, so all code would be in one place:

C#
namespace RandomTest {
    using System.Windows.Forms;

    public partial class FormMain : Form {

        const string ButtonStop = "&Stop";
        const string ButtonStart = "&Start";
        const int SleepTime = 500;

        delegate void NumberAction(Label label, int value);
        //in .NET version above 2.0 this line is not needed
        //use System.Action<Label, int> instead

        public FormMain() {
            Padding = new Padding(10);
            Button button = new Button();
            button.Text = ButtonStart;
            button.Dock = DockStyle.Bottom;
            Controls.Add(button);
            Label output = new Label();
            output.Dock = DockStyle.Fill;
            output.AutoSize = false;
            Controls.Add(output);
            button.Click += delegate(object sender, System.EventArgs eventArgs) {
                if (running) {
                    button.Text = ButtonStart;
                    wrapper.Pause();
                } else {
                    button.Text = ButtonStop;
                    wrapper.Resume();
                } //if
                running = !running;
            }; //button.click 
            wrapper.NumberGenerated += delegate(object sender, ThreadWrapper.NumberGeneratedEventArgs eventArgs) {
                output.Invoke(new NumberAction(delegate(Label label, int value) {
                    label.Text = value.ToString();
                }), output, eventArgs.Number);
            }; //wrapper.NumberGenerated
            wrapper.Start();
            this.Closing += delegate(object sender, System.ComponentModel.CancelEventArgs e) {
                wrapper.Abort();
            };
        } //FormMain

        bool running;
        ThreadWrapper wrapper = new ThreadWrapper(SleepTime);

    } //class FormMain

} //namespace RandomTest


I also tried to use the syntax compatible with C# v.2, which is still used. I also hope it will be easier if you still want to translate it in VB.NET. In later versions, lambda syntax of anonymous delegates is highly beneficial.

As to VB.NET, please see my comment to the question.

This code is fully tested. Again, sorry this is not VB.NET.

—SA
 
Share this answer
 
v5
Please do yourself a favor, don't do Application.DoEvents, especially for this purpose. This is called spin wait and is a bad thing. You should never do any blocking call and never call Thread.Sleep in UI thread. This thread should be kept responsive at all times.

You need to create a separate thread and do your processing in that thread. To notify the UI thread, you need to use UI thread invocation. Please see for further detail:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading in my collection of links to my past answers:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA
 
Share this answer
 
Comments
Tin Christina 2-Jan-12 23:07pm    
thank. I try and really like you said, it's non-stop application :)
But you know, I'm just beginner of VB.net. So if you don't mind. Could you please give me a small example of it. Because I want a button where I can start the loop (show random number after few second each time), but ofcourse I need a button where I can stop that loop.
Thank you, sir.
Sergey Alexandrovich Kryukov 2-Jan-12 23:29pm    
You should tell me if this is Forms or WPF and tag it. Also, it would be C# -- I don't have VB.NET installed; but it's pretty much the same, you only need an idea. How about that?
--SA
Tin Christina 3-Jan-12 0:46am    
yeah, it's pretty much help :)
Tin Christina 3-Jan-12 0:47am    
oh, and my application is just a form
Sergey Alexandrovich Kryukov 3-Jan-12 1:11am    
OK, done; please see my other solution.
--SA
This is a WinForms project, right? Try putting a call to Application.DoEvents() in the loop (before the sleep call); it's possible that the UI thread is not getting a chance to actually update the label before it goes to sleep.
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 2-Jan-12 22:45pm    
Very bad advice, it works but is a constant source of problems, something to avoid; voted 1.
--SA
use setInterval or setTimeout function of java script
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 3-Jan-12 1:23am    
Why did you assume this has anything to do with JavaScript (or "java script", something that does not exist!)?
Completely irrelevant post; sorry, but it does not deserve a vote more than 1.

Please, be a little bit responsible if you are trying to answer questions. Remember, some inquirers are absolute beginners, confusing them could be pretty bad for them, might cause a waste of time or even much worse -- misconceptions.

--SA

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