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. multithread performance problem for web service call

multithread performance problem for web service call

Scheduled Pinned Locked Moved C#
databasesysadminperformancequestionwcf
35 Posts 5 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.
  • Y Yasithl

    as i know thread.join means calling thread waits in indefinitely till the other thread terminated.so it might be the bottle neck. the other thing is usually we use threads for concurrent processing so if we don't ask the threads to wait till other thread comes they will work independently

    yasith

    G Offline
    G Offline
    George_George
    wrote on last edited by
    #8

    Thanks yasith, "so if we don't ask the threads to wait till other thread comes they will work independently" -- I am interested, could you show me your code please? regards, George

    1 Reply Last reply
    0
    • L Lost User

      Maybe a single task is not taking enough time to be worth creating a thread for? If that's the case, try to use the ThreadPool and see if that works better. You don't have to use it "explicitly", creating a delegate and calling BeginInvoke on it should be fine. If you want to wait for all tasks to finish, you could store the IAsyncResults in an array and later call EndInvoke on all of them. edit: lol @ my stupid typo :laugh:


      Last modified: 42mins after originally posted --

      G Offline
      G Offline
      George_George
      wrote on last edited by
      #9

      Thanks harold! I have tried to use thread pool but performance never improves. Here is my code. Any ideas to improve performance? http://www.codeproject.com/script/Forums/View.aspx?fid=1649&msg=2911818[^] regards, George

      L 1 Reply Last reply
      0
      • P PIEBALDconsult

        My understanding is that a web service has only one process at a time, so all requests have to queue up anyway.

        G Offline
        G Offline
        George_George
        wrote on last edited by
        #10

        Thanks PIEBALDconsult! 1. "web service has only one process at a time" -- at client side or server side, do you mean? 2. "web service has only one process at a time" -- any documents to prove your points? I am very interested to learn from it. regards, George

        P 1 Reply Last reply
        0
        • E Ennis Ray Lynch Jr

          Add another NIC. Only one request can go through one network card at a time. Also, in looking at your code you are locking up each thread with your call to hello world. If you had a stack of methods to call say:

          Stack<Service1> clients ...;

          You can then use thread safe code inside of your ThreadJob method to pop a service, call its method and then return. Because each thread is now no longer depended on a given service a slow running server will not tie up the entire operation.

          Need software developed? Offering C# development all over the United States, ERL GLOBAL, Inc is the only call you will have to make.
          If you don't ask questions the answers won't stand in your way.
          Most of this sig is for Google, not ego.

          G Offline
          G Offline
          George_George
          wrote on last edited by
          #11

          Thanks Ennis, Looks like you are an expert of this topic. Cool! I read your reply 3 times but still confused. :-( "You can then use thread safe code inside of your ThreadJob method to pop a service, call its method and then return. " -- it is appreciated if you could show me your code please? Honestly, I never wrote such code before. regards, George

          E 1 Reply Last reply
          0
          • G George_George

            Thanks harold! I have tried to use thread pool but performance never improves. Here is my code. Any ideas to improve performance? http://www.codeproject.com/script/Forums/View.aspx?fid=1649&msg=2911818[^] regards, George

            L Offline
            L Offline
            Lost User
            wrote on last edited by
            #12

            Ok, this may not make much of a difference (if any), but you could use some elements like: (this is not code - just some 'useful' elements) delegate void ThreadJobDelegate(int index); IAsyncResult[] results = new IAsyncResult[number]; ThreadJobDelegate th = new ThreadJobDelegate(ThreadJob); results[index] = th.BeginInvoke(index, null, null); foreach(IAsyncResult res) th.EndInvoke(res); I would also time each call to ThreadJob, it doesn't have to be fancy, just to get an idea of how long each call is taking - and time the total (from before the first BeginInvoke till after the last EndInvoke), to see whether threading improved it at all (and if so, by how much).

            G 1 Reply Last reply
            0
            • L Lost User

              Ok, this may not make much of a difference (if any), but you could use some elements like: (this is not code - just some 'useful' elements) delegate void ThreadJobDelegate(int index); IAsyncResult[] results = new IAsyncResult[number]; ThreadJobDelegate th = new ThreadJobDelegate(ThreadJob); results[index] = th.BeginInvoke(index, null, null); foreach(IAsyncResult res) th.EndInvoke(res); I would also time each call to ThreadJob, it doesn't have to be fancy, just to get an idea of how long each call is taking - and time the total (from before the first BeginInvoke till after the last EndInvoke), to see whether threading improved it at all (and if so, by how much).

              G Offline
              G Offline
              George_George
              wrote on last edited by
              #13

              Thanks harold! I have applied your ideas but performance never improves. Here is my code modified according to your idea. Any ideas? Or anything wrong with my code?

              class Program
              {
                  static Service1\[\] clients = null;
                  static IAsyncResult\[\] results = null;
                  static AsyncMethodCaller\[\] callers = null;
              
                  public delegate void AsyncMethodCaller(object index);
              
                  static void ThreadJob (object index)
                  {
                      // query 100 times
                      for (int i = 0; i < 100; i++)
                      {
                          clients\[(int)index\].HelloWorld();
                      }
                  }
                  
                  static void Main(string\[\] args)
                  {
                      Console.WriteLine("Specify number of threads: ");
                      int number = Int32.Parse(Console.ReadLine());
                      
                      clients = new Service1\[number\];
                      results = new IAsyncResult\[number\];
                      callers = new AsyncMethodCaller\[number\];
              
                      for (int i = 0; i < number; i++)
                      {
                          clients\[i\] = new Service1();
                          clients\[i\].EnableDecompression = true;
                          callers\[i\] = new AsyncMethodCaller(ThreadJob);
                          results\[i\] = callers\[i\].BeginInvoke(i, null, null);
                      }
              
                      DateTime begin = DateTime.Now;
              
                      int j = 0;
                      foreach (IAsyncResult res in results)
                      {
                          callers\[j\].EndInvoke(res);
                          j++;
                      }
              
                      Console.WriteLine("Total elapsed time (s): " + (DateTime.Now - begin).TotalSeconds);
              
                      Console.ReadLine();
              
                      return;
                  }
              }
              

              regards, George

              L 1 Reply Last reply
              0
              • G George_George

                Thanks harold! I have applied your ideas but performance never improves. Here is my code modified according to your idea. Any ideas? Or anything wrong with my code?

                class Program
                {
                    static Service1\[\] clients = null;
                    static IAsyncResult\[\] results = null;
                    static AsyncMethodCaller\[\] callers = null;
                
                    public delegate void AsyncMethodCaller(object index);
                
                    static void ThreadJob (object index)
                    {
                        // query 100 times
                        for (int i = 0; i < 100; i++)
                        {
                            clients\[(int)index\].HelloWorld();
                        }
                    }
                    
                    static void Main(string\[\] args)
                    {
                        Console.WriteLine("Specify number of threads: ");
                        int number = Int32.Parse(Console.ReadLine());
                        
                        clients = new Service1\[number\];
                        results = new IAsyncResult\[number\];
                        callers = new AsyncMethodCaller\[number\];
                
                        for (int i = 0; i < number; i++)
                        {
                            clients\[i\] = new Service1();
                            clients\[i\].EnableDecompression = true;
                            callers\[i\] = new AsyncMethodCaller(ThreadJob);
                            results\[i\] = callers\[i\].BeginInvoke(i, null, null);
                        }
                
                        DateTime begin = DateTime.Now;
                
                        int j = 0;
                        foreach (IAsyncResult res in results)
                        {
                            callers\[j\].EndInvoke(res);
                            j++;
                        }
                
                        Console.WriteLine("Total elapsed time (s): " + (DateTime.Now - begin).TotalSeconds);
                
                        Console.ReadLine();
                
                        return;
                    }
                }
                

                regards, George

                L Offline
                L Offline
                Lost User
                wrote on last edited by
                #14

                Ok that would explain it then I suppose.. It should be possible to use on 1 new AsyncMethodCaller - but I seriously doubt it would have a impact on the performance. If performance can not be improved with threading, then it will just have to be improved in some other way..

                G 1 Reply Last reply
                0
                • L Lost User

                  Ok that would explain it then I suppose.. It should be possible to use on 1 new AsyncMethodCaller - but I seriously doubt it would have a impact on the performance. If performance can not be improved with threading, then it will just have to be improved in some other way..

                  G Offline
                  G Offline
                  George_George
                  wrote on last edited by
                  #15

                  Thanks harold! "It should be possible to use on 1 new AsyncMethodCaller - but I seriously doubt it would have a impact on the performance." -- how could we use only one AsyncMethodCaller instance? Could you show me some simple pseudo code based on my code please? regards, George

                  L 1 Reply Last reply
                  0
                  • G George_George

                    Thanks Ennis, Looks like you are an expert of this topic. Cool! I read your reply 3 times but still confused. :-( "You can then use thread safe code inside of your ThreadJob method to pop a service, call its method and then return. " -- it is appreciated if you could show me your code please? Honestly, I never wrote such code before. regards, George

                    E Offline
                    E Offline
                    Ennis Ray Lynch Jr
                    wrote on last edited by
                    #16

                    Stack<Items> stack ...;

                    public void MyThread(object whocares){
                    while(go){
                    Item item = null;
                    lock(stack){
                    item = stack.Pop();
                    }
                    if(item != null){
                    //Process Item
                    }
                    }
                    }

                    Then you need somewhere to run start the loop

                    System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(MyThread));

                    Now just push items on the stack when they need to be called in another thread. There are many modifications to this basic theme.

                    Need software developed? Offering C# development all over the United States, ERL GLOBAL, Inc is the only call you will have to make.
                    If you don't ask questions the answers won't stand in your way.
                    Most of this sig is for Google, not ego.

                    G 1 Reply Last reply
                    0
                    • G George_George

                      Thanks harold! "It should be possible to use on 1 new AsyncMethodCaller - but I seriously doubt it would have a impact on the performance." -- how could we use only one AsyncMethodCaller instance? Could you show me some simple pseudo code based on my code please? regards, George

                      L Offline
                      L Offline
                      Lost User
                      wrote on last edited by
                      #17

                      Like so:

                      class Program
                      {
                          static Service1\[\] clients = null;
                      
                          public delegate void AsyncMethodCaller(int index);
                      
                          static void ThreadJob (int index)
                          {
                              // query 100 times
                              for (int i = 0; i < 100; i++)
                              {
                                  clients\[index\].HelloWorld();
                              }
                          }
                          
                          static void Main(string\[\] args)
                          {
                              Console.WriteLine("Specify number of threads: ");
                              int number = Int32.Parse(Console.ReadLine());
                              //note: this doesn't actually specify the number of threads
                              //the number of threads will be something like "at most 15 time the number of available cores"
                              //which means that it will only specify the number of threads that are used if
                              //the number if small. And any number of threads may exists - but they wouldn't be used.
                      
                              clients = new Service1\[number\];
                              IAsyncResult\[\] results = new IAsyncResult\[number\];
                      
                              AsyncMethodCaller TJ = new AsyncMethodCaller(ThreadJob)
                              for (int i = 0; i < number; i++)
                              {
                                  clients\[i\] = new Service1();
                                  clients\[i\].EnableDecompression = true;
                                  results\[i\] = TJ.BeginInvoke(i, null, null);
                              }
                      
                              DateTime begin = DateTime.Now;
                      
                              foreach (IAsyncResult res in results)
                                  TJ.EndInvoke(res);
                      
                              Console.WriteLine("Total elapsed time (s): " + (DateTime.Now - begin).TotalSeconds);
                      
                              Console.ReadLine();
                      
                              return;
                          }
                      }
                      
                      G 1 Reply Last reply
                      0
                      • G George_George

                        Thanks PIEBALDconsult! 1. "web service has only one process at a time" -- at client side or server side, do you mean? 2. "web service has only one process at a time" -- any documents to prove your points? I am very interested to learn from it. regards, George

                        P Offline
                        P Offline
                        PIEBALDconsult
                        wrote on last edited by
                        #18

                        1. Server side, the service doesn't run on the client. 2. If I did, I would have given a more authoritative answer.

                        G 1 Reply Last reply
                        0
                        • E Ennis Ray Lynch Jr

                          Stack<Items> stack ...;

                          public void MyThread(object whocares){
                          while(go){
                          Item item = null;
                          lock(stack){
                          item = stack.Pop();
                          }
                          if(item != null){
                          //Process Item
                          }
                          }
                          }

                          Then you need somewhere to run start the loop

                          System.Threading.ThreadPool.QueueUserWorkItem(new System.Threading.WaitCallback(MyThread));

                          Now just push items on the stack when they need to be called in another thread. There are many modifications to this basic theme.

                          Need software developed? Offering C# development all over the United States, ERL GLOBAL, Inc is the only call you will have to make.
                          If you don't ask questions the answers won't stand in your way.
                          Most of this sig is for Google, not ego.

                          G Offline
                          G Offline
                          George_George
                          wrote on last edited by
                          #19

                          Thanks Ennis, I have some confusion about your soluton. I think the reason of why you use stack is because there are some shared object instances between the threads, correct? But in my situation, there is no shared items between my thread jobs. You can read my code again for my thread job in method "ThreadJob". Any comments? Please feel free to correct me if I am wrong. :-) regards, George

                          1 Reply Last reply
                          0
                          • P PIEBALDconsult

                            1. Server side, the service doesn't run on the client. 2. If I did, I would have given a more authoritative answer.

                            G Offline
                            G Offline
                            George_George
                            wrote on last edited by
                            #20

                            Thanks PIEBALDconsult! If the bottleneck is "web service has only one process at a time", how do you prove it or show some related documents? regards, George

                            P 1 Reply Last reply
                            0
                            • L Lost User

                              Like so:

                              class Program
                              {
                                  static Service1\[\] clients = null;
                              
                                  public delegate void AsyncMethodCaller(int index);
                              
                                  static void ThreadJob (int index)
                                  {
                                      // query 100 times
                                      for (int i = 0; i < 100; i++)
                                      {
                                          clients\[index\].HelloWorld();
                                      }
                                  }
                                  
                                  static void Main(string\[\] args)
                                  {
                                      Console.WriteLine("Specify number of threads: ");
                                      int number = Int32.Parse(Console.ReadLine());
                                      //note: this doesn't actually specify the number of threads
                                      //the number of threads will be something like "at most 15 time the number of available cores"
                                      //which means that it will only specify the number of threads that are used if
                                      //the number if small. And any number of threads may exists - but they wouldn't be used.
                              
                                      clients = new Service1\[number\];
                                      IAsyncResult\[\] results = new IAsyncResult\[number\];
                              
                                      AsyncMethodCaller TJ = new AsyncMethodCaller(ThreadJob)
                                      for (int i = 0; i < number; i++)
                                      {
                                          clients\[i\] = new Service1();
                                          clients\[i\].EnableDecompression = true;
                                          results\[i\] = TJ.BeginInvoke(i, null, null);
                                      }
                              
                                      DateTime begin = DateTime.Now;
                              
                                      foreach (IAsyncResult res in results)
                                          TJ.EndInvoke(res);
                              
                                      Console.WriteLine("Total elapsed time (s): " + (DateTime.Now - begin).TotalSeconds);
                              
                                      Console.ReadLine();
                              
                                      return;
                                  }
                              }
                              
                              G Offline
                              G Offline
                              George_George
                              wrote on last edited by
                              #21

                              Thanks harold, I have tried but no performance improvements. Do you have any other ideas to improve performance? I find CPU/memory/network are used a little part, so I think there is room to improve performance. regards, George

                              L 1 Reply Last reply
                              0
                              • G George_George

                                Thanks harold, I have tried but no performance improvements. Do you have any other ideas to improve performance? I find CPU/memory/network are used a little part, so I think there is room to improve performance. regards, George

                                L Offline
                                L Offline
                                Lost User
                                wrote on last edited by
                                #22

                                Very strange.. I'm really out of ideas now.. :( There is just 1 explanation I can think of - the web server is handling all requests sequentially and non-pipelined.

                                G 1 Reply Last reply
                                0
                                • L Lost User

                                  Very strange.. I'm really out of ideas now.. :( There is just 1 explanation I can think of - the web server is handling all requests sequentially and non-pipelined.

                                  G Offline
                                  G Offline
                                  George_George
                                  wrote on last edited by
                                  #23

                                  Thanks harold, Two more questions, 1. My code is posted and simple. Could you reproduce my issue? I am not suspecting it is my environment issue. :-) 2. "the web server is handling all requests sequentially and non-pipelined" -- do you have any ways or documents to prove it? regards, George

                                  L 1 Reply Last reply
                                  0
                                  • G George_George

                                    Thanks PIEBALDconsult! If the bottleneck is "web service has only one process at a time", how do you prove it or show some related documents? regards, George

                                    P Offline
                                    P Offline
                                    PIEBALDconsult
                                    wrote on last edited by
                                    #24

                                    I don't know, I'm not a Web expert, I'm hoping someone with more knowledge will step in and answer that for both of us. You could possibly create a Web Service with two methods, one that sleeps for a minute and one that doesn't. Make a request to the one that sleeps, and while it's sleeping make a request to the other and see whether or not it waits for the sleeping one to complete.

                                    G 1 Reply Last reply
                                    0
                                    • G George_George

                                      Thanks harold, Two more questions, 1. My code is posted and simple. Could you reproduce my issue? I am not suspecting it is my environment issue. :-) 2. "the web server is handling all requests sequentially and non-pipelined" -- do you have any ways or documents to prove it? regards, George

                                      L Offline
                                      L Offline
                                      Lost User
                                      wrote on last edited by
                                      #25

                                      1. no, I would have to know what HelloWorld() does, and how it does it, and probably a lot more 2. well, if it weren't, threading would cause a speed-up. And it didn't.

                                      G 1 Reply Last reply
                                      0
                                      • P PIEBALDconsult

                                        I don't know, I'm not a Web expert, I'm hoping someone with more knowledge will step in and answer that for both of us. You could possibly create a Web Service with two methods, one that sleeps for a minute and one that doesn't. Make a request to the one that sleeps, and while it's sleeping make a request to the other and see whether or not it waits for the sleeping one to complete.

                                        G Offline
                                        G Offline
                                        George_George
                                        wrote on last edited by
                                        #26

                                        Thanks PIEBALDconsult, I am not sure what you are going to prove. In your scenario, you have web service (say sleep) and another web service (say sleepless). If we call on a thread from client side, first call sleep web service, then call sleepless web service, since it is synchronous call in one thread from client, the client will definitely wait for the sleep web service to complete the return results until call the second sleepless web service. Please correct me if I am wrong in understanding your points. I am confused what you are going to prove -- so obvious results. :-) regards, George

                                        P 1 Reply Last reply
                                        0
                                        • L Lost User

                                          1. no, I would have to know what HelloWorld() does, and how it does it, and probably a lot more 2. well, if it weren't, threading would cause a speed-up. And it didn't.

                                          G Offline
                                          G Offline
                                          George_George
                                          wrote on last edited by
                                          #27

                                          Thanks harold, For 1, Here is my code at server side. Could you reproduce my problem?

                                          /// <summary>
                                          /// Summary description for Service1
                                          /// </summary>
                                          \[WebService(Namespace = "http://tempuri.org/")\]
                                          \[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1\_1)\]
                                          \[System.ComponentModel.ToolboxItem(false)\]
                                          public class Service1 : System.Web.Services.WebService
                                          {
                                          
                                              \[WebMethod\]
                                              public double HelloWorld()
                                              {
                                                  return new Random().NextDouble();
                                              }
                                          }
                                          

                                          For 2, I could understand your points. But do you have any documents to prove? I think if web service could only serve requests sequentially other than simualtenaously, it is so bad and degrade performance design. I can not believe it is designed in this way. :-) regards, George

                                          L 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