1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Threading best practises for bots threads/ tasks / parallel

Discussion in 'C, C++, C#' started by something77, Jul 11, 2012.

  1. something77

    something77 Registered Member

    Joined:
    Jan 6, 2010
    Messages:
    73
    Likes Received:
    10
    I have been looking into this off and on for a while but haven't come up with a best practise solution. Was wondering how others multi thread potentially long running tasks, signup / content creating posting etc

    Tasks and parallel are pretty much the same, using the thread pool and being managed when to fire off a new task if the taskscheduler thinks improvements are gained by starting another. Parallel has the benefit that you can set the parallel option MaxDegreeOfParallelism rather than having to code basic scheduler that checks how many tasks are running if you want to limit this. But tasks do allow you to cancel a specific task via a canceltoken, whereas the parallel canceltoken works across all tasks.

    Threads are nice as you know each task is running in a thread, but are not managed so nicely and can lead to a few more leaks. Had an app that after running for a day was reported as using 2000 threads and had caused the server to crawl along, oops lol

    So what do you use, when and why?

    Threads
    Code:
    var list = new List<Thread>();
    Thread t = new Thread( ()=>{
       doWorrk();
    });
    list.add(t);
    
    Tasks
    Code:
    //can use cancellation tokens but off the top of my head I cannot remember the syntax
    var list = new List<Task>();
    Task t = new Task( ()=>{
       doWork();
    });
    t.start();
    list.add(t);
    
    
    Parallel
    Code:
    parallel.foreach(list, (line)=>{
       doWork(line);
    });
    
     
  2. Chris22

    Chris22 Regular Member

    Joined:
    Sep 29, 2010
    Messages:
    400
    Likes Received:
    1,059
    For me it really depends on what the thread is doing, I sort of use a mix between TPL and regular Thread objects. I'm quite fond of the System.Collections.Concurrent namespace too :d
     
  3. theMagicNumber

    theMagicNumber Regular Member

    Joined:
    May 13, 2010
    Messages:
    345
    Likes Received:
    195
    Code:
            void Init()
            {
                int THREADS = 1;
                List<Thread> trs = new List<Thread>();
                for (int i = 0; i < THREADS; i++)
                {
                    Thread tr = new Thread(Worker);
                    trs.Add(tr);
                    tr.Start();
                }
                foreach (Thread tr in trs)
                {
                    tr.Join();
                }
            }
    
    
            void Worker()
            {
                string current = string.Empty;
                while (true)
                {
                    if (!queue.TryDequeue(out current))
                    {
                        return;
                    }
                    try
                    {
                           //Do the work here.
                    }
                    catch (Exception ex)
                    {
    
    
                    }
                }
            }
    
    
            ConcurrentQueue<string> queue = new ConcurrentQueue<string>();
    
    I usually use similar pattern to the above. Each thread creates its own stack, so the Worker function is safe. However you have to implement your own stop/pause method. For example if you need to download X web pages, just load the queue object with the urls and implement the logic in the try/catch block. The System.Collections.Concurrent namespace seems to be good, BlockingCollection can be used to easily implement Producer/Consumer scenario.

    PS: you have to wait for the threads to finish(Join) and never use Abort or Interrupt, it is a bad practice and can lead to corrupted data and unexpectable results. Another note using Abort/Interrupt doesn't guarantee that the thread will finish immediately.
     
    Last edited: Jul 11, 2012
  4. something77

    something77 Registered Member

    Joined:
    Jan 6, 2010
    Messages:
    73
    Likes Received:
    10
    Am not aware of the concurrent namespace, will go check it out.

    Can you explain what you mean by "safe"

    Am not sure if this is a real example or not, but for download webpages, isn't using threads overkill? Wouldn't asyc webrequests be better?

    I;ve been reading up quite abit on stackoverflow, and from what I understand at the moment, async requests are best if just pulling a page, tasks parallel.foreach if is a relatively short tasks (but more than just pulling apage and processing that content) and threads if is going to be an ongoing / long process. Although the task can be start with the longrunningtask option, I haven't got my head round if this is better than using a thread.