我有点内存分配的n00b,但我试图了解如何使用AsyncCallbacks与BeginInvoke类型设计模式可能会导致内存分配,从而可能导致更频繁地调用垃圾收集器。
例如,如果我有一个带有一个事件的类,我希望与回调异步调用,我通常会按如下方式设置它:
public class PriceBook
{
private double Value;
public void UpdateValue(double Value)
{
this.Value = Value;
}
public event EventHandler ValueUpdated;
private void DoValueUpdated(double Value)
{
if (ValueUpdated != null)
{
ValueUpdated.BeginInvoke(this, EventArgs.Empty, ValueUpdateCompleted, Value);
}
}
private void ValueUpdateCompleted(IAsyncResult ar)
{
// Do something when event has finished being called.
}
}
我工作的人说,以这种方式调用BeginInvoke实际上是通过每次调用时创建一个新的AsyncCallback来分配内存。所以,他建议这样做:
public class PriceBook
{
private AsyncCallback ValueUpdateCallback;
private double Value;
public PriceBook1()
{
ValueUpdateCallback = ValueUpdateCompleted;
}
public void UpdateValue(double Value)
{
this.Value = Value;
DoValueUpdated(Value);
}
public event EventHandler ValueUpdated;
private void DoValueUpdated(double Value)
{
if (ValueUpdated != null)
{
ValueUpdated.BeginInvoke(this, EventArgs.Empty, ValueUpdateCallback, Value);
}
}
private void ValueUpdateCompleted(IAsyncResult ar)
{
// Do something when event has finished being called.
}
}
如您所见,这里我在构造函数中设置了一次AsyncCallback。方法II真的可以节省内存分配吗?这两种方法还有其他任何好处/是否有更好的方法来完成我想要做的事情?
答案 0 :(得分:2)
是的,这可以节省一个代表分配。
此
ValueUpdated.BeginInvoke(..., ValueUpdateCompleted, ...);
真的是这样的:
ValueUpdated.BeginInvoke(..., new AsyncCallback(ValueUpdateCompleted), ...);
您现在可以看到分配。
如果调用不在热路径上,意味着它不是性能关键,我建议不来缓存委托,因为代码可维护性正在受到影响。
此外,线程池调用比委托分配要昂贵得多。我无法想象这可能会产生影响的情况。