Delegate.BeginInvoke 与 ThreadPool.QueueWorkerUserItem

发布于 2024-11-02 08:37:13 字数 1797 浏览 0 评论 0原文

    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);
    }

我应该使用这两个中的哪一个? (哪个表现更好?) 为什么?
我的方法的开销是否会影响决策,或者这些实现之一总是优于另一个?
出于什么原因?

我倾向于 ThreadPool.QueueWorkerUserItem 但我不知道哪个实际上更好,无论是在这种情况下还是在一般

更新

我读了一些关于 TPL 的东西..解决了这个问题:

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

    }

我该怎么办在这里处理异常?我的意思是,如果我这样做,

    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);
        }**
    }

我是否错过了并行性的全部要点?

我不应该只处理 RequestQueueHandler.RequestQueue.Add 方法中可能抛出的异常吗?

    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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我很坚强 2024-11-09 08:37:13

Delegate.BeginInvoke() 方法也使用 ThreadPool,因此不要期望性能上有任何有意义的差异。

QueueUserWorkItem() 并不是直接更好,只是在大多数情况下更容易。

但请注意,这两个示例都缺少错误处理。
你漂亮的短委托需要一个 try/catch,BeginInvoke 场景需要一个回调。

因此,当您可以使用 Fx4 时,您应该使用 TPL 来获得更高的抽象级别。

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.

旧夏天 2024-11-09 08:37:13

异步委托为您提供了更多功能:返回值和异常转发(您应该调用 EndInvoke 来访问它们)。
通过直接使用 ThreadPool,您必须自己处理。

另一方面,ThreadPool 的优点是简单。

请看一下这本优秀的在线书籍,其中讨论了两种(以及更多)方法深度。

经验法则:

  • 如果可以的话,请使用 TPL;
  • ,则直接使用 ThreadPool 来执行简单的即发即忘任务
  • 如果不使用异步委托

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
眼睛会笑 2024-11-09 08:37:13

ThreadPool.QueueWorkerUserItem 级别更高,也是首选。
但是ThreadPool.QueueWorkerUserItem在幕后使用Delegate.BeginInvoke
但是 Delegate.BeginInvoke 使用 ThreadPool 中的线程。

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文