Click here to Skip to main content
15,885,216 members
Please Sign up or sign in to vote.
2.33/5 (3 votes)
See more:
Hello all,

My problem is that I have this method and I don't know how to use the Timer class to slow down the FOR. At the moment I am using the Thread.Sleep but I really hate it because it makes the interface "dead" until the script is done.

How can I change the script in such a way to use the Timer Class instead of the Thread.Sleep so that I can use the UI while the script is still running?

C#
private void ProcessCsvFile(string pFileContent)
       {
           //set the delimiters for string seperation
           string[] stringSeparators = new string[] { "\r\n" };
           //now the file content gets split into an array where each line of the .csv-file gets into on element of the array
           string[] dataLines = pFileContent.Split(stringSeparators, StringSplitOptions.None);

           // X = counter for how many orders have been sent
           int x = 0;
           //Check if there is a Session ID
           string CookieID = textBox1.Text;
           if (string.IsNullOrEmpty(CookieID))
           {
              SystemSounds.Beep.Play();
              MessageBox.Show("Please provide a session ID!");
           }
           else
           {
               //loop over all of the lines
               for (int i = 0; i < dataLines.Length; i++)
               {

                   //dont process the first line, since its the description line
                   if (i != 0 && dataLines[i] != "")
                   {
                       x++;
                       //split line by ;
                       string[] csvColumns = dataLines[i].Split(',');

                       label3.Text = x.ToString();
                       label3.Refresh();

                       // Send order based on ID, Count and Price
                       Send_BuyOrder(csvColumns[0], csvColumns[1], csvColumns[2]);
                       // Write in the data grid
                       dataGridView1.Rows.Add(csvColumns[0], csvColumns[1], csvColumns[2], "Done");
                       dataGridView1.Refresh();
                       // Sleep for 4seconds
                       if (x < dataLines.Length -1)
                       {
                           Thread.Sleep(4300);
                       }

                   }
               }
               SystemSounds.Beep.Play();
               MessageBox.Show(x + " orders have been set!");
           }
       }
Posted
Updated 28-Aug-14 9:35am
v2
Comments
Richard MacCutchan 28-Aug-14 15:32pm    
And your question is ... ?
[no name] 28-Aug-14 15:34pm    
You don't.
Sergey Alexandrovich Kryukov 28-Aug-14 15:36pm    
The whole idea of "slowing down for" with a timer looks really bad. I don't say you don't need to "slow down" — maybe you need to. If you explain your ultimate goal, the behavior you want to have, not how, I'll be able to help you, almost certainly.
Short hint: forget timer, use an extra thread.
—SA
Arthfael 28-Aug-14 15:40pm    
Well, I have a CSV file that has ID's / Count and Price for a couple of products that I buy on a daily basis. The method parses the file and sends a HTTP POST request every 4.3seconds but because I am using the Thread.Sleep, the UI is blocked until the script is done. (it takes 5-10minutes to process and send all the requests)
Sergey Alexandrovich Kryukov 28-Aug-14 15:47pm    
Certainly, use a separate thread. 100% certainly. I would also question the need of regular POST, but the alternative would be using server push, not a very usual stuff.
—SA

I agree with using a Thread rather than a Timer.

Unlike Sleep, Join "Blocks the calling thread until a thread terminates, while continuing to perform standard COM and SendMessage pumping."

http://msdn.microsoft.com/en-us/library/95hbf2ta(v=vs.110).aspx[^]

So here's a simple little experiment in wrapping a Sleep in a Thread and then Joining on it:

C#
public static void
SleepWalk
(
  int millisecondsTimeout
)
{
  System.Threading.Thread t = new System.Threading.Thread
  (
    delegate() { System.Threading.Thread.Sleep ( millisecondsTimeout ) ; }
  )
  {
    IsBackground = true
  ,
    Priority = System.Threading.ThreadPriority.Lowest
  } ;

  t.Start() ;

  t.Join() ;

  return ;
}


It seems to work.

I also agree that maybe you need to rethink your design.
 
Share this answer
 
Comments
Dave Kreskowiak 28-Aug-14 19:35pm    
I never thought of that. Pretty slick!
PIEBALDconsult 28-Aug-14 19:59pm    
Never occured to me until now. But I often use Join after spawning off a bunch of threads.
To keep the UI responsive during busy processes you can use the Application.DoEvents method

http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents(v=vs.110).aspx[^]
 
Share this answer
 
Comments
Sergey Alexandrovich Kryukov 28-Aug-14 15:45pm    
Ryan, this is a really, really bad approach which can cause many problems. A real (and even the simplest way) would be using an extra thread.
I did not answer because I wanted to wait OP's explanation of the purpose.
—SA
ZurdoDev 28-Aug-14 15:50pm    
Extra thread is another option. More complicated but still an option.

DoEvents() is still supported in .Net 4.5 so Microsoft must not think it is too bad of an option. It's certainly easier than multiple threads. :)
Sergey Alexandrovich Kryukov 28-Aug-14 16:00pm    
I disagree. No, an extra thread is less complicated... DoEvents works, but is a source of troubles. :-)
—SA
ZurdoDev 28-Aug-14 16:02pm    
Out of curiosity, what kind of troubles? I used it many years ago but have been doing web since.
Sergey Alexandrovich Kryukov 28-Aug-14 16:06pm    
Hard to answer quickly, as I was careful to avoid it for a long time. But, basically, it potentially makes UI thread not responsive, because it can be hard to guarantee that the time slices between DoEvents are small enough. Worse, it can create infinite recursion, and broken order of execution, because some calls between DoEvents may also invoke events. It can become a bomb of deferred action...
—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