Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Multithreaded function calls

Multithreaded function calls

Scheduled Pinned Locked Moved C#
designalgorithmsannouncementworkspace
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Kenneth Haugland
    wrote on last edited by
    #1

    Assume that I have a pipe that consists of sections of variable radiuses and that I want to make calculations at different frequencies. So I want the calculations done at different threads for each frequency, but the list of pipe sections stays the same.

    public class PipeSection
    {
        public PipeSection(double radius)
        {
            this.Radius = radius;
        }
    
        public double Radius { get; set; }
    
    
        public double Calculate(double Frequency)
        {
            return Frequency \* this.Radius;
        }
    
    }
    

    To run the frequencies in parallel I use Rx:

    CancellationTokenSource ctr = new CancellationTokenSource();
    List wn = new List();

        public MainWindow()
        {
            InitializeComponent();
    
            PipeSection\[\] input = { new PipeSection(5), new PipeSection(6), new PipeSection(7) };
    
            wn.AddRange(input);
    
            //Calcualte at the frequencies 0,100,2000,3000
            var FreqData = new double\[\] { 0, 100, 2000, 3000 }.ToObservable();
    
            FreqData
                //Off the ui thread
                .ObserveOn(Scheduler.Default)
                //Run each thread seperatly
                .SelectMany(x => Task.Run(() => DoCalcualtions(x,wn), ctr.Token))
                //Back to the UI thread
                .ObserveOnDispatcher()
                //Subscribe and start the calcualtions
                .Subscribe(args => {
                                    //Update the progressbar when a thread is completed
                                    pgbProgress.Value += 1;
                                    //Tell me what thread is completed
                                    txtText.Text += Environment.NewLine + args.ToString();
                                    },
                            () => {
                                    //All done, here I could do sorting etc.
                                    txtText.Text += Environment.NewLine + "All done";
                                  }
                            );
        }
    
        private double DoCalcualtions(double Freq, List input)
        {
            double result=1;
            for (int i = 0; i < input.Count(); i++)
                result \*= input\[i\].Calculate(Freq);
    
            return result;
        }
    

    This does compile and run, but I have some questions regarding if the multithread calls: 1) Will I h

    S 1 Reply Last reply
    0
    • K Kenneth Haugland

      Assume that I have a pipe that consists of sections of variable radiuses and that I want to make calculations at different frequencies. So I want the calculations done at different threads for each frequency, but the list of pipe sections stays the same.

      public class PipeSection
      {
          public PipeSection(double radius)
          {
              this.Radius = radius;
          }
      
          public double Radius { get; set; }
      
      
          public double Calculate(double Frequency)
          {
              return Frequency \* this.Radius;
          }
      
      }
      

      To run the frequencies in parallel I use Rx:

      CancellationTokenSource ctr = new CancellationTokenSource();
      List wn = new List();

          public MainWindow()
          {
              InitializeComponent();
      
              PipeSection\[\] input = { new PipeSection(5), new PipeSection(6), new PipeSection(7) };
      
              wn.AddRange(input);
      
              //Calcualte at the frequencies 0,100,2000,3000
              var FreqData = new double\[\] { 0, 100, 2000, 3000 }.ToObservable();
      
              FreqData
                  //Off the ui thread
                  .ObserveOn(Scheduler.Default)
                  //Run each thread seperatly
                  .SelectMany(x => Task.Run(() => DoCalcualtions(x,wn), ctr.Token))
                  //Back to the UI thread
                  .ObserveOnDispatcher()
                  //Subscribe and start the calcualtions
                  .Subscribe(args => {
                                      //Update the progressbar when a thread is completed
                                      pgbProgress.Value += 1;
                                      //Tell me what thread is completed
                                      txtText.Text += Environment.NewLine + args.ToString();
                                      },
                              () => {
                                      //All done, here I could do sorting etc.
                                      txtText.Text += Environment.NewLine + "All done";
                                    }
                              );
          }
      
          private double DoCalcualtions(double Freq, List input)
          {
              double result=1;
              for (int i = 0; i < input.Count(); i++)
                  result \*= input\[i\].Calculate(Freq);
      
              return result;
          }
      

      This does compile and run, but I have some questions regarding if the multithread calls: 1) Will I h

      S Offline
      S Offline
      Sascha Lefevre
      wrote on last edited by
      #2

      As long as your threads don't modify the data they're reading it's all perfectly thread-safe. No need to clone the data or to move DoCalcualtions. Moving DoCalcualtions into the PipeSection class wouldn't make a lot of sense anyway because it doesn't operate on a single PipeSection instance. I assume in practice your input data set is a lot larger so threading is actually called for? There are of course alternative ways of doing this but I don't think there's an objectively better way. You're aware that you're ignoring the CancellationToken in DoCalcualtions ?

      If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson

      K 1 Reply Last reply
      0
      • S Sascha Lefevre

        As long as your threads don't modify the data they're reading it's all perfectly thread-safe. No need to clone the data or to move DoCalcualtions. Moving DoCalcualtions into the PipeSection class wouldn't make a lot of sense anyway because it doesn't operate on a single PipeSection instance. I assume in practice your input data set is a lot larger so threading is actually called for? There are of course alternative ways of doing this but I don't think there's an objectively better way. You're aware that you're ignoring the CancellationToken in DoCalcualtions ?

        If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson

        K Offline
        K Offline
        Kenneth Haugland
        wrote on last edited by
        #3

        Thank you for the answer. I understand that they are thread safe, but what I was worried about was that there was just "one function" in memory, so when it was used no other threads could use the function, thereby making the multithreading single thread instead? (So I tried (and failed) to described a wrapper class that had several instances of the function in memory). As for the reasoning behind using multithreading, the datasets itself are not so large, but I'm going to do some numerical integration inside DoCalcualtions that is very time-consuming. As for the non-use of

        CancellationToken

        I just stripped the calculations to the bare minimum. Kenneth

        S 1 Reply Last reply
        0
        • K Kenneth Haugland

          Thank you for the answer. I understand that they are thread safe, but what I was worried about was that there was just "one function" in memory, so when it was used no other threads could use the function, thereby making the multithreading single thread instead? (So I tried (and failed) to described a wrapper class that had several instances of the function in memory). As for the reasoning behind using multithreading, the datasets itself are not so large, but I'm going to do some numerical integration inside DoCalcualtions that is very time-consuming. As for the non-use of

          CancellationToken

          I just stripped the calculations to the bare minimum. Kenneth

          S Offline
          S Offline
          Sascha Lefevre
          wrote on last edited by
          #4

          Kenneth Haugland wrote:

          what I was worried about was that there was just "one function" in memory, so when it was used no other threads could use the function, thereby making the multithreading single thread instead?

          No, there's no such thing as automatic method-entry-queuing. That's why there are synchronization objects. If you don't use any your threads will execute whatever "comes their way".

          If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson

          K 1 Reply Last reply
          0
          • S Sascha Lefevre

            Kenneth Haugland wrote:

            what I was worried about was that there was just "one function" in memory, so when it was used no other threads could use the function, thereby making the multithreading single thread instead?

            No, there's no such thing as automatic method-entry-queuing. That's why there are synchronization objects. If you don't use any your threads will execute whatever "comes their way".

            If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson

            K Offline
            K Offline
            Kenneth Haugland
            wrote on last edited by
            #5

            If I read you correctly, each thread will have its own function to use?

            S 1 Reply Last reply
            0
            • K Kenneth Haugland

              If I read you correctly, each thread will have its own function to use?

              S Offline
              S Offline
              Sascha Lefevre
              wrote on last edited by
              #6

              Code (instructions) only exist(s) once in memory and that's not a problem because it (usually) never changes. But each thread has its own stack for local variable allocation. When thread #2 enters DoCalcualtions while thread #1 is still executing DoCalcualtions they will have individual "instances" of the local variable result. Ref: memory management - What and where are the stack and heap? - Stack Overflow[^]

              If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups