11

I need to start a thread, but continue just after the thread is actually running. Now my code looks like:

        splashthread.IsBackground = false;
        splashthread.Start();
        Thread.Sleep(100); // Wait for the thread to start

I'm not fond of these voodoo sleeps (to say the least), so I'm looking for more nifty way of doing the above.

Any ideas?

Guy L
  • 2,824
  • 2
  • 27
  • 37

2 Answers2

25

Something like this:

var splashStart = new ManualResetEvent(false);

var splashthread = new Thread(
  () =>
  {
     splashStart.Set();
     // Your thread code here...
  });

splashthread.Start();
splashStart.WaitOne();

Don't forget to Dipose splashStart or if it's appropriate in your code use a using block.

Edit: Didn't confirm the original code in the IDE. Changed Wait to WaitOne() as per comment below.

Ilian
  • 5,113
  • 1
  • 32
  • 41
  • Thanks, lambda functions are nice, but I actually moved the event the class itself... and the function is WaitOne() BTW – Guy L Oct 08 '11 at 23:25
  • Right, it might also be preferable to use the newer ManualResetEventSlim wich uses spincount – Polity Oct 09 '11 at 02:06
  • @gonzobrains: `ManualResetEvent` holds a native resource and you probably don't want to wait until finalization for it to be freed. In general, it's good practice to call `Dispose` when using types that derive from IDisposable after using them. See these more for info: http://stackoverflow.com/q/5895879/324260, http://stackoverflow.com/q/2871888/324260. – Ilian Apr 09 '13 at 02:02
  • @gonzobrains: Another link: http://stackoverflow.com/q/1832992/324260. The MSDN article on IDisposable is also informative: http://msdn.microsoft.com/en-au/library/system.idisposable.aspx – Ilian Apr 09 '13 at 02:04
1

Why do you care when the other thread starts? You well may be interested in knowing when the new thread has reached some particular milestone, and you could use any number of synchronization primitives to deal with that (in addition to events, if the new thread is going to be initializing something visible to the constructing thread, you could use a monitor lock with Monitor.Wait/Monitor.Pulse. Monitor locks are lightweight, but require a little care.

In particular, the thread which is going to wait for the other thread must check within a synclock whether the object has been initialized, before it does Monitor.Wait. Otherwise it's possible that the new thread might perform its Monitor.Pulse before the main thread has reached its Monitor.Wait. Adding the object-initialized check would prevent that scenario. If the new thread hasn't initialized the object before the launcher thread entered the synclock to check and wait, it won't be able to perform the Pulse until after the launcher thread gives up its lock via Monitor.Wait. If the new thread has initialized the object before the launcher thread entered the synclock, the launcher thread will see that and not wait at all.

supercat
  • 77,689
  • 9
  • 166
  • 211
  • I'm trying to create a splash screen: http://www.codeproject.com/KB/dotnet/Yet_Another_Splash_Screen.aspx. For some reason the labels didn't change if the thread didn't start. – Guy L Oct 09 '11 at 01:24