mr.*_*r.b 11 c# mono delegates function-pointers
我需要能够使用Mono在C#中基于函数指针调用单个方法.代表工作正常,这是他们的目的,但是每次我设置委托时它们似乎分配了52个字节(不是+ =,而只是使用=设置它所以总是只有一个方法被委托引用).
这个委托每秒更改很多次,它导致GC定期启动,我想避免.
我不介意初始内存分配,但有没有办法在每次更改单个委托值时阻止分配?
如果没有,除了每次更改地址时都不会分配任何内存的委托之外,还有其他动态方法来调用C#中的方法吗?
你写的任何代码都是这样的
Action action = foo.DoSomething;
Run Code Online (Sandbox Code Playgroud)
结束编译成这个
Action action = new Action(foo.DoSomething);
Run Code Online (Sandbox Code Playgroud)
这是分配的来源.没有任何完美的方法可以解决这个问题,但是要阻止缓存和重用委托所需的分配.
您可以通过为每个方法创建委托来在实现方面实现此目的.
public class Foo
{
public void DoSomething() { /*nop*/ }
private Action _doSomethingDelegate;
public Action DoSomethingDelegate
{
get { return _doSomethingDelegate ?? (_doSomethingDelegate = DoSomething); }
}
}
Run Code Online (Sandbox Code Playgroud)
那么你只需引用现有的委托而不是方法
Action action = foo.DoSomethingDelegate;
Run Code Online (Sandbox Code Playgroud)
另一个选择是使用某种缓存类,但这会引入一堆对象生命周期问题,这些问题在游戏场景中可能是您不想要的.这是一个粗略的实现是真实的可能想要使用弱引用.
public static class DelegateCache
{
private static readonly Dictionary<object, Dictionary<string, Delegate>> Cache = new Dictionary<object, Dictionary<string, Delegate>>();
private static Dictionary<string, Delegate> GetObjectCache(object instance)
{
Dictionary<string, Delegate> delegates;
if (!Cache.TryGetValue(instance, out delegates))
{
Cache[instance] = delegates = new Dictionary<string, Delegate>();
}
return delegates;
}
public static T GetDelegate<T>(object instance, string method)
where T: class
{
var delegates = GetObjectCache(instance);
Delegate del;
if (!delegates.TryGetValue(method, out del))
{
delegates[method] = del = Delegate.CreateDelegate(typeof(T), instance, method);
}
return del as T;
}
}
Run Code Online (Sandbox Code Playgroud)
使用它将看起来像这样
Action action = DelegateCache.GetDelegate<Action>(foo, "DoSomething");
Run Code Online (Sandbox Code Playgroud)
运行一些测试这两种方法每个对象/方法对只有一个分配.我可能会去实施方面修复它虽然很多工作,但它更清洁.如果有很多方法并且您计划添加更多方法,则可以使用T4生成具有方法的委托实现的分部类.
| 归档时间: |
|
| 查看次数: |
1508 次 |
| 最近记录: |