0

I'm still getting the handle of .NET 4 multithreading libraries so I'm not sure if they're more helpful here than a lower level solution.

I have a BlockingCollection of messages which need to be send to some HTTP service endpoint. Normally my solution would be to create an infinite looping function like so

void DoWork()
{
    while(true)
    {
        var message = collection.Take();
        SendMessage();
    }
}

start X number of Thread() objects to work the loop. The multiple threads account for the time spent waiting for HTTP responses then I'd profile and tune the performance to figure out the correct number of threads to use.

Is this a better fit for tasks?

Piers MacDonald
  • 563
  • 1
  • 5
  • 18
  • Consider using asynchronous IO. It's completely unnecessary to tie up threads waiting for IO. TPL defaults to using the ThreadPool which will quickly starve if you're placing lots long-lived blocking jobs into it. – spender Feb 26 '14 at 03:44
  • Don't use worker threads. Use naturally async API, e.g. `HttpClient`, like [this](http://stackoverflow.com/a/22002868/1768303). – noseratio Feb 26 '14 at 07:14

3 Answers3

2

There no much difference when you use Task or Thread in this case. both are going to do same thing.

I'd rather write this using GetConsumingEnumerable so that it gets out when there are no elements.

void DoWork()
{
    foreach(var message in collection.GetConsumingEnumerable())
    {
        SendMessage();
    }
}
Sriram Sakthivel
  • 72,067
  • 7
  • 111
  • 189
  • I don't want this to ever exit. Messages are generated by user input, there could be 10000 in a second or one in 10000 seconds. I want this thing to wait patiently for some to show up but never stop. – Piers MacDonald Feb 26 '14 at 03:42
  • @PiersMacDonald `GetConsumingEnumerable` will never return till you call `blockingCollection.CompleteAdding` Till then it will block. Read about [GetConsumingEnumerable](http://msdn.microsoft.com/en-us/library/dd395014%28v=vs.110%29.aspx) – Sriram Sakthivel Feb 26 '14 at 03:46
  • Right, but then the foreach will run and the function will exit. That is not what the OP wants. – Ed S. Feb 26 '14 at 03:48
  • 1
    @EdS. You should read about `GetConsumingEnumerable`. It will not return control. It will block and never exits the function till you dispose the collection or call `CompleteAdding`. My code is semantically equal to Op's code. Simply this method never ends if `CompleteAdding` is not called. That's the beauty of `GetConsumingEnumerable` – Sriram Sakthivel Feb 26 '14 at 03:54
  • 1
    Ah thanks. I assumed it have behaviour like a normal fixed enumerable where it would return after ending. Very cool to know, thanks! I could have used a while(!collection.IsCompleted) I suppose but I never want this thing to stop. – Piers MacDonald Feb 26 '14 at 05:42
  • @SriramSakthivel: Ok, I suppose I misunderstood the documentation. That's handy, I've never seen it before. Learned something. +1 – Ed S. Feb 26 '14 at 07:02
0

I'm not going to offer my opinion on which you should use, but I will offer a couple guidelines.

This post : https://stackoverflow.com/a/4130204/3317555 offers some very good guidance. Since you are getting up to speed with .NET 4, you might want to try both and see which style you like better in terms of functionality and how it looks in your code.

EDIT: I will say this, don't use Parallel.

Community
  • 1
  • 1
bubbinator
  • 487
  • 2
  • 7
  • In my experience, `Parallel` has a habit of using all my CPU cores, which it's designed to do. That can make the UI less responsive. Also, take a quick look through [the exposed methods of the class](http://msdn.microsoft.com/en-us/library/system.threading.tasks.parallel(v=vs.110).aspx). From your posts, it seems like you are looking for an `async` approach. Parallel is great for getting things done, but not for waiting. – bubbinator Mar 04 '14 at 19:38
0

From MSDN - "Starting with the .NET Framework 4, the TPL is the preferred way to write multithreaded and parallel code."

http://msdn.microsoft.com/en-us/library/dd460717.aspx

I found Parallel.ForEach() is good at such tasks. It optimizes the number of threads. It accounts for the number of cores in the system and also what the threads are doing.

Yousuf
  • 3,105
  • 7
  • 28
  • 38