2

I was wondering if anyone knew how to make a delay on c# that delays one thing that is happening but not everything else? What I am doing is that it places blocks, and i have it delay, but the player (also places blocks to move) gets that delay too. I am currently using:

Thread.Sleep(200);

But is there another to create a delay for one event without delaying all the other events?

user2997877
  • 65
  • 2
  • 9
  • Threads http://msdn.microsoft.com/en-us/library/3e8s7xdd(v=vs.110).aspx Tasks http://cplus.about.com/od/learnc/a/multi-threading-using-task-parallel-library.htm – mattanja Apr 05 '14 at 21:25

4 Answers4

2

You could just use a timer to handle it - if you use windows Forms, use the System.Windows.Forms.Timer and put the delayed code in the Tick EventHandler. Start the timer and then exit your method. The Eventhandler will be called when the Tick Event occurs. With this you can get around using any sort of multithreading, since windows uses the UI Thread to call the Tick Eventhandler.

//Put this on modular level so you can access it later on
private System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();


   /* Adds the event and the event handler for the method that will 
   process the timer event to the timer. Put this into your method instead of Thread.Sleep(200)*/
   myTimer.Tick += new EventHandler(myTimer_Tick);

   // Sets the timer interval to 200 milliseconds.
   myTimer.Interval = 200;
   myTimer.Start();

//Here's your event handler - stop the timer so it doesn't reexecute
private void myTimer_Tick(Object myObject, EventArgs myEventArgs) 
{
    myTimer.Stop();
    //Execute delayed action here   

}
Marwie
  • 3,177
  • 3
  • 28
  • 49
  • Any particular reason you chose Window.Forms.Timer instead of Threading.Timer or Timers.TImer? Unless you are already in a winforms app, those would be more "normal" timers to use. Also, while this solves the problem it doesn't address the OPs clear lack of understanding of threads. – BradleyDotNET Apr 05 '14 at 21:43
  • @LordTakkera: just trying to keep things easy - since the Threading.Timer or Timers.Timer will use another thread to do stuff and so imply working in a multithreaded environment. – Marwie Apr 05 '14 at 21:45
  • Given the use case, he may want to be in one anyways... I understand your logic though. Thank you also for the clarification that this solution is intended for a windows forms project. +1 – BradleyDotNET Apr 05 '14 at 21:50
0

Without more information it's hard to say. My guess is that all your UI rendering is being done on a single thread, so when you call Thread.Sleep() you're effectively pausing the entire application.

Martin Costello
  • 9,672
  • 5
  • 60
  • 72
0

The answer to this question lies in understanding how threads work. A thread is a "line" of program execution. Because our computers run many programs (but only have one CPU) it is necessary for the OS to be able to stop one "line" and allow another to run. These "lines" are called threads.

When a thread is "paused" it is said that it is "blocked". Threads can block themselves (allowing other threads to run) as well. That is effectively what Thread.Sleep does, it blocks the executing thread and will not run again until the specified time interval elapses.

If you do this on your main (UI) thread, then your UI will not update and no other code on that thread will run until it is unblocked. With your scenario, it sounds like you need a thread for your "computer player" to place blocks and then sleep for a while. By the way a timer is basically just a nice wrapper for this same behavior (spin a thread, wait for the interval, recall, repeat).

In other words, Thread.Sleep does far more than just "delay" an action, to use it effectively you need to make sure you understand your code's threading model. It sounds like you are always on the UI thread, and you probably need to start some of your own.

Note that if you are not on the UI thread, you need to perform UI tasks in an Invoke method. This pushes execution of that code onto the UI thread.

Let me know if I can be of further assistance!

BradleyDotNET
  • 60,462
  • 10
  • 96
  • 117
0

You can use tasks as well to delay code execution:

Task.Delay(200).ContinueWith((t) => World.Blocks[215, 273] = block)

Reading further on SO reveals that a Task.Delay uses a Timer underneath.

Community
  • 1
  • 1
Measurity
  • 1,316
  • 1
  • 12
  • 24