Delegate.BeginInvoke 与 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);
}
我应该使用这两个中的哪一个? (哪个表现更好?) 为什么?
我的方法的开销是否会影响决策,或者这些实现之一总是优于另一个?
出于什么原因?
我倾向于 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
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.
异步委托为您提供了更多功能:返回值和异常转发(您应该调用 EndInvoke 来访问它们)。
通过直接使用 ThreadPool,您必须自己处理。
另一方面,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:
ThreadPool.QueueWorkerUserItem
级别更高,也是首选。但是ThreadPool.QueueWorkerUserItem
在幕后使用Delegate.BeginInvoke
。但是
Delegate.BeginInvoke
使用ThreadPool
中的线程。ThreadPool.QueueWorkerUserItem
is higher level and preferred.ButThreadPool.QueueWorkerUserItem
behind the scene usesDelegate.BeginInvoke
.But
Delegate.BeginInvoke
uses threads from theThreadPool
.