1

I am teaching myself C# from my usual C++ programming and now I'm doing threads.

The following simple code compiles fine and should output beeps on a loop via threads for 30 seconds.

using System;
using System.Runtime.InteropServices;
using System.Threading;

class BeepSample
{
    [DllImport("kernel32.dll", SetLastError=true)]
    static extern bool Beep(uint dwFreq, uint dwDuration);

    static void Main()
    {
        Console.WriteLine("Testing PC speaker...");
        for (uint i = 100; i <= 20000; i++)
        {
            var BeepThread = new Thread(delegate() { Beep(i, 30000); });            
        }

        Console.WriteLine("Testing complete.");
        Console.ReadLine();
    }
}

Only problem is the threads don't seem to work.

I know I am missing something basic.

Any ideas?

loumbut5
  • 65
  • 8
  • *As soon as you type `new Thread()`, it's over; your project already has legacy code.* Concurrency in C# Cookbook, @StephenCleary –  Aug 18 '16 at 07:14

3 Answers3

3

Your forgot to start thread MSDN link

for (uint i = 100; i <= 20000; i++)
{
    var BeepThread = new Thread(delegate() { Beep(i, 30000); });
    BeepThread.Start();
}

However that looks suspicious. Why would you need 19900 threads? Probably you want to have 1 thread, that has a loop inside and pauses for short periods to output different frequency through beeper.

dlxeon
  • 1,932
  • 1
  • 11
  • 14
2

Only problem is the threads don't seem to work.

This aspect is clear from the part that you have not started the threads for them to do anything

Code has many other issues:

  • Closure issue, needs further modification as

    for (uint i = 100; i <= 20000; i++)
    {
      int icopy = i;
      var BeepThread = new Thread(delegate() { Beep(icopy, 30000); });    
      BeepThread.Start();        
    }
    
  • Thread class will start the foreground threads and each logical processor core has capacity to process one thread at a time and each Thread is a very costly resource for the computation and memory as it needs allocation of Thread Environment Block, Kernel Stack Memory, User Stack Memory, the current code even if it runs, will kill your system and you mostly have to kill the process to come out of it

  • Console.ReadLine(); will only block the Main Thread / Ui Thread, others threads being foreground will go on even if Main thread / Ui thread exits and not blocked, ideal way to block is calling Join on each Thread object, which will ask Main thread to wait till its complete

  • One of the preferred way to re-write the same code is using the Task Parallel Library:

     Parallel.For(100, 20000,
     , new ParallelOptions { MaxDegreeOfParallelism =  
    Environment.ProcessorCount } 
    i =>
    {
       int icopy = i;
        Beep(icopy, 30000);
    });
    

Benefits:

  • Code doesn't create so many threads and kill the system
  • Works on thread pool (Background threads) and use only required number of threads are invoked and max number never exceeds the Processor count of the system and would be mostly far lesser, as threads are reused since there's no major long running computation
  • Automatically blocks Main thread / Ui Thread
Mrinal Kamboj
  • 11,300
  • 5
  • 40
  • 74
0

Ok, thanks guys. Had gone for lunch.

I implemented...

for (uint i = 500; i <= 550; i++)
    {
        uint icopy = i;
        var BeepThread = new Thread(delegate() { Beep(icopy, 30000); });
        BeepThread.Start(); 
    }

Which worked great.

As predicted the threads did not terminate after the main thread was executed but it does what I want which is awesome.

Bless y'all.

loumbut5
  • 65
  • 8