使用CallSite

时间:2016-12-28 02:24:07

标签: c# asp.net-mvc dynamic memory-leaks

让我说我有一个html帮助器,在某些时候调用

 GetDynamicValueOrNull(html.ViewBag, "SomePropName")

private static object GetDynamicValueOrNull(dynamic dyn, string memberName)
{
    var dynamicObj = dyn as DynamicObject;

    if (dynamicObj == null) 
    {
        return null;
    }

    return dynamicObj.GetDynamicMemberNames().Contains(memberName)
        ? ExtractDynamicMember(dynamicObj, memberName)
        : null;
}

private static object ExtractDynamicMember(object obj, string memberName)
{
    var binder = Binder.GetMember(CSharpBinderFlags.None, memberName, obj.GetType(),
         new[] { CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) });
    var callsite = CallSite<Func<CallSite, object, object>>.Create(binder);
    return callsite.Target(callsite, obj);
}

问题是,在某些时候,这段代码变成了一个带有堆栈跟踪的大内存泄漏:

Stack trace:    at System.Collections.Generic.Dictionary`2.Resize(Int32 newSize, Boolean forceNewHashCodes)
   at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
   at Microsoft.CSharp.RuntimeBinder.Semantics.SYMTBL.InsertChildNoGrow(Symbol child)
   at Microsoft.CSharp.RuntimeBinder.Semantics.SymFactoryBase.newBasicSym(SYMKIND kind, Name name, ParentSymbol parent)
   at Microsoft.CSharp.RuntimeBinder.Semantics.SymFactory.CreateLocalVar(Name name, ParentSymbol parent, CType type)
   at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.PopulateLocalScope(DynamicMetaObjectBinder payload, Scope pScope, ArgumentObject[] arguments, IEnumerable`1 parameterExpressions, Dictionary`2 dictionary)
   at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.BindCore(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding)
   at Microsoft.CSharp.RuntimeBinder.RuntimeBinder.Bind(DynamicMetaObjectBinder payload, IEnumerable`1 parameters, DynamicMetaObject[] args, DynamicMetaObject& deferredBinding)
   at Microsoft.CSharp.RuntimeBinder.BinderHelper.Bind(DynamicMetaObjectBinder action, RuntimeBinder binder, IEnumerable`1 args, IEnumerable`1 arginfos, DynamicMetaObject onBindingError)
   at Microsoft.CSharp.RuntimeBinder.CSharpGetMemberBinder.FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
   at System.Dynamic.DynamicObject.MetaDynamic.CallMethodWithResult(String methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback, Fallback fallbackInvoke)
   at System.Dynamic.DynamicObject.MetaDynamic.CallMethodWithResult(String methodName, DynamicMetaObjectBinder binder, Expression[] args, Fallback fallback)
   at System.Dynamic.DynamicObject.MetaDynamic.BindGetMember(GetMemberBinder binder)
   at System.Dynamic.DynamicMetaObjectBinder.Bind(Object[] args, ReadOnlyCollection`1 parameters, LabelTarget returnLabel)
   at System.Runtime.CompilerServices.CallSiteBinder.BindCore[T](CallSite`1 site, Object[] args)
   at System.Dynamic.UpdateDelegates.UpdateAndExecute1[T0,TRet](CallSite site, T0 arg0)
   at System.Web.Mvc.MyHelperName.ExtractDynamicMember(Object obj, String memberName)
   ...

我听说这可能是因为DLR缓存政策,这是正确的,是否有适用于此案例的解决方法/修复方法?

0 个答案:

没有答案