bevacqua
bevacqua

Reputation: 48476

Delegate.BeginInvoke vs ThreadPool.QueueWorkerUserItem

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        var replyCopy = reply;

        ThreadPool.QueueUserWorkItem(delegate
        {
            RequestQueueHandler.RequestQueue.Add((Message)correlationState, replyCopy);
        });
    }

vs

    private delegate void RequestQueueHandlerAdd(Message request, Message reply);

    private static void AsyncMethod(Message request, Message reply)
    {
        RequestQueueHandler.RequestQueue.Add(request, reply);
    }

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        ((RequestQueueHandlerAdd)AsyncMethod).BeginInvoke((Message)correlationState, reply, null, null);
    }

which of these two should I use? (which performs better?) why?
does the overhead of my method influence the decision or does one of these implementation always outperform the other?
for what reason?

I'm inclined towards ThreadPool.QueueWorkerUserItem but I have no clue which one is actually better, neither in this case nor in general

UPDATE

I read some stuff about TPL.. worked this out:

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        var replyCopy = reply;
        var enqueue = Task.Factory.StartNew(() => RequestQueueHandler.RequestQueue.Add((Message)correlationState, replyCopy));

    }

how am I supposed to handle the exception here? I mean, if I do

    public void BeforeSendReply(ref Message reply, object correlationState)
    {
        var replyCopy = reply;
        var enqueue = Task.Factory.StartNew(() => RequestQueueHandler.RequestQueue.Add((Message) correlationState, replyCopy));

        **try
        {
            enqueue.Wait();
        }
        catch(AggregateException e)
        {
            Handle(e);
        }**
    }

Am I not missing the whole point of parallelism here?

Shouldn't I just handle the possible exception throw in the RequestQueueHandler.RequestQueue.Add method?

Upvotes: 6

Views: 3982

Answers (3)

grzeg
grzeg

Reputation: 358

Asynchronuous delegates give you a bit more: return values and exception forwarding (you should call EndInvoke to get access to them). By using ThreadPool directly you have to take care of that yourself.

ThreadPool's advantage on the other hand is simplicity.

Do have a look at this excellent online book, which discusses the two (and more) approaches in depth.

As a rule of a thumb:

  • use TPL if you can
  • if not use ThreadPool directly for simple fire-and-forget tasks
  • if not use async delegates

Upvotes: 2

Henk Holterman
Henk Holterman

Reputation: 273169

The Delegate.BeginInvoke() method also uses the ThreadPool, so don't expect any meaningful difference in performance.

QueueUserWorkItem() isn't directly better, just easier in most cases.

But note that both samples are missing Error handling.
Your nice short delegate needs a try/catch, the BeginInvoke scenario a Callback.

So when you can use Fx4 you ought to use the TPL for a much higher abstraction level.

Upvotes: 3

Aliostad
Aliostad

Reputation: 81660

ThreadPool.QueueWorkerUserItem is higher level and preferred. But ThreadPool.QueueWorkerUserItem behind the scene uses Delegate.BeginInvoke. But Delegate.BeginInvoke uses threads from the ThreadPool.

Upvotes: 1

Related Questions