Exemple #1
0
        public void RecentlyUsedLookupTest()
        {
            string value;

            MruCache <int, string> mruCache = new MruCache <int, string>(100);

            for (int i = 0; i < 200; ++i)
            {
                mruCache.TryAddValue(i, i.ToString());
                for (int j = 0; j < i; j += 10)
                {
                    Assert.True(mruCache.TryGetValue(j, out value));
                    Assert.Equal(j.ToString(), value);
                }
            }

            for (int j = 0; j < 100; j += 10)
            {
                Assert.True(mruCache.TryGetValue(j, out value));
                Assert.Equal(j.ToString(), value);
            }

            for (int i = 170; i < 200; ++i)
            {
                Assert.True(mruCache.TryGetValue(i, out value));
                Assert.Equal(i.ToString(), value);
            }
        }
        public void TryRemove_returns_false_for_unknown_entry()
        {
            var cache = new MruCache <int, string>(capacity: 3);

            cache.Add(1, "one");

            Assert.False(cache.TryRemove(2, out var removed));
            Assert.Null(removed);
        }
        private MruCache <string, HttpClient> EnsureHttpClientCache()
        {
            if (_httpClientCache == null || !_httpClientCache.AddRef())
            {
                _httpClientCache = new MruCache <string, HttpClient>(10);
            }

            return(_httpClientCache);
        }
 public void Clear()
 {
     lock (this.mutex)
     {
         if (this.tokenCache != null)
         {
             this.tokenCache = new MruCache <TokenProvider.Key, TokenProvider.TokenInfo>(this.cacheSize);
         }
     }
 }
 public AsyncWaitCallbackMethodExecutor(CodeActivityMetadata metadata, MethodInfo asyncMethod, Activity invokingActivity,
                                        Type targetType, InArgument targetObject, Collection <Argument> parameters,
                                        RuntimeArgument returnObject,
                                        MruCache <MethodInfo, Func <object, object[], object> > funcCache,
                                        ReaderWriterLockSlim locker)
     : base(invokingActivity, targetType, targetObject, parameters, returnObject)
 {
     Fx.Assert(asyncMethod != null, "Must provide asyncMethod");
     this.asyncMethod = asyncMethod;
     this.asyncFunc   = MethodCallExpressionHelper.GetFunc(metadata, asyncMethod, funcCache, locker);
 }
 internal WorkflowDefinitionDispenser(WorkflowRuntime runtime, bool validateOnCreate, int capacity)
 {
     if (capacity <= 0)
     {
         capacity = 0x7d0;
     }
     this.workflowRuntime       = runtime;
     this.workflowTypes         = new MruCache(capacity, this, CacheType.Type);
     this.xomlFragments         = new MruCache(capacity, this, CacheType.Xoml);
     this.workflowOutParameters = new Dictionary <Type, List <PropertyInfo> >();
     this.parametersLock        = new ReaderWriterLock();
     this.validateOnCreate      = validateOnCreate;
 }
        public void when_TryGetValue_called_with_existing_key__should_return_what_it_was_provided()
        {
            var mruCache = new MruCache<ValueWrapper<int>, object>(12);

            object added = new object();
            var key = new ValueWrapper<int>(0);

            mruCache.Add(key, added);

            object res;
            Assert.IsTrue(mruCache.TryGetValue(new ValueWrapper<int>(0), out res));
            Assert.AreEqual(added, res);
        }
        public void when_TryGetValue_called_with_nonexistent_key__should_return_false()
        {
            var mruCache = new MruCache<ValueWrapper<int>, object>(12);

            object added = new object();
            var key = new ValueWrapper<int>(0);

            mruCache.Add(key, added);

            object res;
            Assert.IsFalse(mruCache.TryGetValue(new ValueWrapper<int>(1), out res));
            Assert.IsNull(res);
        }
 public AsyncPatternMethodExecutor(CodeActivityMetadata metadata, MethodInfo beginMethod, MethodInfo endMethod,
                                   Activity invokingActivity, Type targetType, InArgument targetObject,
                                   Collection <Argument> parameters, RuntimeArgument returnObject,
                                   MruCache <MethodInfo, Func <object, object[], object> > funcCache,
                                   ReaderWriterLockSlim locker)
     : base(invokingActivity, targetType, targetObject, parameters, returnObject)
 {
     Fx.Assert(beginMethod != null && endMethod != null, "Must provide beginMethod and endMethod");
     this.beginMethod = beginMethod;
     this.endMethod   = endMethod;
     this.beginFunc   = MethodCallExpressionHelper.GetFunc(metadata, beginMethod, funcCache, locker);
     this.endFunc     = MethodCallExpressionHelper.GetFunc(metadata, endMethod, funcCache, locker);
 }
Exemple #10
0
        public void when_TryGetValue_called_with_nonexistent_key__should_return_false()
        {
            var mruCache = new MruCache <ValueWrapper <int>, object>(12);

            object added = new object();
            var    key   = new ValueWrapper <int>(0);

            mruCache.Add(key, added);

            object res;

            Assert.IsFalse(mruCache.TryGetValue(new ValueWrapper <int>(1), out res));
            Assert.IsNull(res);
        }
Exemple #11
0
        public void when_TryGetValue_called_with_existing_key__should_return_what_it_was_provided()
        {
            var mruCache = new MruCache <ValueWrapper <int>, object>(12);

            object added = new object();
            var    key   = new ValueWrapper <int>(0);

            mruCache.Add(key, added);

            object res;

            Assert.IsTrue(mruCache.TryGetValue(new ValueWrapper <int>(0), out res));
            Assert.AreEqual(added, res);
        }
        public void Clear_removes_all_entries()
        {
            var cache = new MruCache <int, string>(capacity: 3);

            cache.Add(1, "one");
            cache.Add(2, "two");
            cache.Add(3, "three");

            cache.Clear();

            Assert.False(cache.TryGetValue(1, out _));
            Assert.False(cache.TryGetValue(2, out _));
            Assert.False(cache.TryGetValue(3, out _));
        }
Exemple #13
0
        public static Func <object[], TResult> GetFunc <TResult>
        (
            CodeActivityMetadata metadata
            , ConstructorInfo constructorInfo
            , MruCache <ConstructorInfo, Func <object[], TResult> > cache
            , ReaderWriterLockSlim locker
        )
        {
            Func <object[], TResult> func = null;

            if (constructorInfo != null)
            {
                locker.EnterWriteLock();
                try
                {
                    cache.TryGetValue(constructorInfo, out func);
                }
                finally
                {
                    locker.ExitWriteLock();
                }
            }
            if (func == null)
            {
                func = GetFunc <TResult>(metadata, constructorInfo);
                if (constructorInfo != null)
                {
                    locker.EnterWriteLock();
                    try
                    {
                        //MruCache has on ContainsKey(), so we use TryGetValue()
                        Func <object[], TResult> result = null;
                        if (!cache.TryGetValue(constructorInfo, out result))
                        {
                            cache.Add(constructorInfo, func);
                        }
                        else
                        {
                            func = result;
                        }
                    }
                    finally
                    {
                        locker.ExitWriteLock();
                    }
                }
            }
            return(func);
        }
        public void TryRemove_removes_existing_entries()
        {
            var cache = new MruCache <int, string>(capacity: 3);

            cache.Add(1, "one");
            cache.Add(2, "two");
            cache.Add(3, "three");

            Assert.True(cache.TryRemove(1, out var removed));
            Assert.AreEqual("one", removed);
            Assert.False(cache.TryGetValue(1, out _));

            Assert.True(cache.TryGetValue(2, out _));
            Assert.True(cache.TryGetValue(3, out _));
        }
Exemple #15
0
        public void SimpleCacheAddAndLookupTest()
        {
            MruCache <int, string> mruCache = new MruCache <int, string>(100);

            for (int i = 0; i < 100; ++i)
            {
                mruCache.TryAddValue(i, i.ToString());
            }

            string value;

            for (int i = 0; i < 100; ++i)
            {
                Assert.True(mruCache.TryGetValue(i, out value));
                Assert.Equal(i.ToString(), value);
            }

            Assert.False(mruCache.TryGetValue(101, out value));
        }
        public void TryGetValue_renews_lifespan_of_entry()
        {
            var cache = new MruCache <int, string>(capacity: 3);

            cache.Add(1, "one");
            cache.Add(2, "two");
            cache.Add(3, "three");

            Assert.True(cache.TryGetValue(3, out _));
            Assert.True(cache.TryGetValue(2, out _));
            Assert.True(cache.TryGetValue(1, out _));

            cache.Add(4, "four");

            Assert.True(cache.TryGetValue(1, out _));
            Assert.True(cache.TryGetValue(2, out _));
            Assert.False(cache.TryGetValue(3, out _));
            Assert.True(cache.TryGetValue(4, out _));
        }
        public void Add_expires_last_used_entry_when_at_capacity()
        {
            var cache = new MruCache <int, string>(capacity: 3);

            cache.Add(1, "one");
            cache.Add(2, "two");
            cache.Add(3, "three");

            Assert.True(cache.TryGetValue(1, out _));
            Assert.True(cache.TryGetValue(2, out _));
            Assert.True(cache.TryGetValue(3, out _));

            cache.Add(4, "four");

            Assert.False(cache.TryGetValue(1, out _));
            Assert.True(cache.TryGetValue(2, out _));
            Assert.True(cache.TryGetValue(3, out _));
            Assert.True(cache.TryGetValue(4, out _));
        }
Exemple #18
0
        public void OverflowCacheAndLookupTest()
        {
            MruCache <int, string> mruCache = new MruCache <int, string>(100);

            for (int i = 0; i < 200; ++i)
            {
                mruCache.TryAddValue(i, i.ToString());
            }

            string value;

            Assert.False(mruCache.TryGetValue(0, out value));
            Assert.False(mruCache.TryGetValue(90, out value));

            for (int i = 120; i < 200; ++i)
            {
                Assert.True(mruCache.TryGetValue(i, out value));
                Assert.Equal(i.ToString(), value);
            }
        }
Exemple #19
0
        public void OverflowFreshCacheAndLookupTest()
        {
            string value;
            MruCache <int, string> mruCache = new MruCache <int, string>(100);

            for (int i = 0; i < 200; ++i)
            {
                mruCache.TryAddValue(i, i.ToString());
                Assert.True(mruCache.TryGetValue(i, out value));    // No longer a virgin
                Assert.Equal(i.ToString(), value);
            }

            for (int j = 0; j < 2; ++j)
            {
                for (int i = 110; i < 200; ++i)
                {
                    if (!mruCache.TryGetValue(i, out value))
                    {
                        mruCache.TryAddValue(i, i.ToString());
                        Assert.True(mruCache.TryGetValue(i, out value));
                    }
                }
            }

            for (int i = 300; i < 310; ++i)
            {
                mruCache.TryAddValue(i, i.ToString());
            }

            int cacheCount = 0;

            for (int i = 110; i < 200; ++i)
            {
                if (mruCache.TryGetValue(i, out value))
                {
                    ++cacheCount;
                }
            }

            Assert.True(cacheCount > 60);   // See that old cache was not killed
        }
        internal static Func <object, object[], object> GetFunc(CodeActivityMetadata metadata, MethodInfo methodInfo,
                                                                MruCache <MethodInfo, Func <object, object[], object> > cache, ReaderWriterLockSlim locker, bool valueTypeReference = false)
        {
            Func <object, object[], object> func = null;

            locker.EnterWriteLock();
            try
            {
                cache.TryGetValue(methodInfo, out func);
            }
            finally
            {
                locker.ExitWriteLock();
            }
            if (func == null)
            {
                func = GetFunc(metadata, methodInfo, valueTypeReference);
                locker.EnterWriteLock();
                try
                {
                    //MruCache has on ContainsKey(), so we use TryGetValue()
                    Func <object, object[], object> result = null;
                    if (!cache.TryGetValue(methodInfo, out result))
                    {
                        cache.Add(methodInfo, func);
                    }
                    else
                    {
                        func = result;
                    }
                }
                finally
                {
                    locker.ExitWriteLock();
                }
            }
            return(func);
        }
Exemple #21
0
        public void OverflowVersionCacheAndLookupTest()
        {
            string value;
            MruCache <int, string> mruCache = new MruCache <int, string>(100);

            for (int i = 0; i < 200; ++i)
            {
                mruCache.TryAddValue(i, i.ToString());
                Assert.True(mruCache.TryGetValue(i, out value));    // No longer a virgin
                Assert.Equal(i.ToString(), value);
            }

            for (int i = 0; i < 90; ++i)
            {
                Assert.False(mruCache.TryGetValue(i, out value));
            }

            for (int i = 140; i < 200; ++i)
            {
                Assert.True(mruCache.TryGetValue(i, out value));
                Assert.Equal(i.ToString(), value);
            }
        }
Exemple #22
0
        // Set methodExecutor, returning an error string if there are any problems (ambiguous match, etc.).
        public void DetermineMethodInfo(CodeActivityMetadata metadata, MruCache<MethodInfo, Func<object, object[], object>> funcCache, ReaderWriterLockSlim locker, 
            ref MethodExecutor methodExecutor)
        {
            bool returnEarly = false;

            MethodExecutor oldMethodExecutor = methodExecutor;
            methodExecutor = null;
            if (string.IsNullOrEmpty(this.MethodName))
            {
                metadata.AddValidationError(SR.ActivityPropertyMustBeSet("MethodName", this.Parent.DisplayName));
                returnEarly = true;
            }

            Type targetType = this.TargetType;

            // If TargetType and the type of TargetObject are both set, it's an error.
            if (targetType != null && this.TargetObject != null && !this.TargetObject.IsEmpty)
            {
                metadata.AddValidationError(SR.TargetTypeAndTargetObjectAreMutuallyExclusive(this.Parent.GetType().Name, this.Parent.DisplayName));
                returnEarly = true;
            }

            // If TargetType was set, look for a static method. If TargetObject was set, look for an instance method. They can't both be set.
            BindingFlags bindingFlags = this.TargetType != null ? staticBindingFlags : instanceBindingFlags;
            string bindingType = bindingFlags == staticBindingFlags ? staticString : instanceString;

            if (targetType == null)
            {
                if (this.TargetObject != null && !this.TargetObject.IsEmpty)
                {
                    targetType = this.TargetObject.ArgumentType;
                }
                else
                {
                    metadata.AddValidationError(SR.OneOfTwoPropertiesMustBeSet("TargetObject", "TargetType", this.Parent.GetType().Name, this.Parent.DisplayName));
                    returnEarly = true;
                }
            }

            // We've had one or more constraint violations already
            if (returnEarly)
            {
                return;
            }

            // Convert OutArgs and InOutArgs to out/ref types before resolution
            Type[] parameterTypes =
                Parameters.Select(argument => argument.Direction == ArgumentDirection.In ? argument.ArgumentType : argument.ArgumentType.MakeByRefType())
                    .ToArray();

            Type[] genericTypeArguments = this.GenericTypeArguments.ToArray();

            InheritanceAndParamArrayAwareBinder methodBinder = new InheritanceAndParamArrayAwareBinder(targetType, genericTypeArguments, this.Parent);

            // It may be possible to know (and check) the resultType even if the result won't be assigned anywhere.     
            // Used 1.) for detecting async pattern, and 2.) to make sure we selected the correct MethodInfo.
            Type resultType = this.ResultType;

            if (this.RunAsynchronously)
            {
                int formalParamCount = parameterTypes.Length;
                Type[] beginMethodParameterTypes = new Type[formalParamCount + 2];
                for (int i = 0; i < formalParamCount; i++)
                {
                    beginMethodParameterTypes[i] = parameterTypes[i];
                }
                beginMethodParameterTypes[formalParamCount] = typeof(AsyncCallback);
                beginMethodParameterTypes[formalParamCount + 1] = typeof(object);

                Type[] endMethodParameterTypes = { typeof(IAsyncResult) };

                this.beginMethod = Resolve(targetType, "Begin" + this.MethodName, bindingFlags,
                    methodBinder, beginMethodParameterTypes, genericTypeArguments, true);
                if (this.beginMethod != null && !this.beginMethod.ReturnType.Equals(typeof(IAsyncResult)))
                {
                    this.beginMethod = null;
                }
                this.endMethod = Resolve(targetType, "End" + this.MethodName, bindingFlags,
                    methodBinder, endMethodParameterTypes, genericTypeArguments, true);
                if (this.endMethod != null && resultType != null && !TypeHelper.AreTypesCompatible(this.endMethod.ReturnType, resultType))
                {
                    metadata.AddValidationError(SR.ReturnTypeIncompatible(this.endMethod.ReturnType.Name, MethodName, targetType.Name, this.Parent.DisplayName, resultType.Name));
                    this.endMethod = null;
                    return;
                }

                if (this.beginMethod != null && this.endMethod != null && this.beginMethod.IsStatic == this.endMethod.IsStatic)
                {
                    if (!(oldMethodExecutor is AsyncPatternMethodExecutor) ||
                        !((AsyncPatternMethodExecutor)oldMethodExecutor).IsTheSame(this.beginMethod, this.endMethod))
                    {
                        methodExecutor = new AsyncPatternMethodExecutor(metadata, this.beginMethod, this.endMethod, this.Parent, 
                            this.TargetType, this.TargetObject, this.Parameters, this.Result, funcCache, locker);
                    }
                    else
                    {
                        methodExecutor = new AsyncPatternMethodExecutor((AsyncPatternMethodExecutor)oldMethodExecutor, 
                            this.TargetType, this.TargetObject, this.Parameters, this.Result);
                    }
                    return;
                }
            }

            MethodInfo result;
            try
            {
                result = Resolve(targetType, this.MethodName, bindingFlags,
                    methodBinder, parameterTypes, genericTypeArguments, false);
            }
            catch (AmbiguousMatchException)
            {
                metadata.AddValidationError(SR.DuplicateMethodFound(targetType.Name, bindingType, MethodName, this.Parent.DisplayName));
                return;
            }

            if (result == null)
            {
                metadata.AddValidationError(SR.PublicMethodWithMatchingParameterDoesNotExist(targetType.Name, bindingType, MethodName, this.Parent.DisplayName));
                return;
            }
            else if (resultType != null && !TypeHelper.AreTypesCompatible(result.ReturnType, resultType))
            {
                metadata.AddValidationError(
                    SR.ReturnTypeIncompatible(result.ReturnType.Name, MethodName,
                        targetType.Name, this.Parent.DisplayName, resultType.Name));
                return;
            }
            else
            {
                this.syncMethod = result;
                if (this.RunAsynchronously)
                {
                    if (!(oldMethodExecutor is AsyncWaitCallbackMethodExecutor) ||
                        !((AsyncWaitCallbackMethodExecutor)oldMethodExecutor).IsTheSame(this.syncMethod))
                    {
                        methodExecutor = new AsyncWaitCallbackMethodExecutor(metadata, this.syncMethod, this.Parent, 
                            this.TargetType, this.TargetObject, this.Parameters, this.Result, funcCache, locker);
                    }
                    else
                    {
                        methodExecutor = new AsyncWaitCallbackMethodExecutor((AsyncWaitCallbackMethodExecutor)oldMethodExecutor,
                            this.TargetType, this.TargetObject, this.Parameters, this.Result);
                    }

                }
                else if (!(oldMethodExecutor is SyncMethodExecutor) ||
                    !((SyncMethodExecutor)oldMethodExecutor).IsTheSame(this.syncMethod))
                {
                    methodExecutor = new SyncMethodExecutor(metadata, this.syncMethod, this.Parent, this.TargetType,
                        this.TargetObject, this.Parameters, this.Result, funcCache, locker);
                }
                else
                {
                    methodExecutor = new SyncMethodExecutor((SyncMethodExecutor)oldMethodExecutor, this.TargetType,
                        this.TargetObject, this.Parameters, this.Result);
                }

            }
        }
Exemple #23
0
 public AsyncPatternMethodExecutor(CodeActivityMetadata metadata, MethodInfo beginMethod, MethodInfo endMethod,
     Activity invokingActivity, Type targetType, InArgument targetObject,
     Collection<Argument> parameters, RuntimeArgument returnObject,
      MruCache<MethodInfo, Func<object, object[], object>> funcCache,
     ReaderWriterLockSlim locker)
     : base(invokingActivity, targetType, targetObject, parameters, returnObject)
 {
     Fx.Assert(beginMethod != null && endMethod != null, "Must provide beginMethod and endMethod");
     this.beginMethod = beginMethod;
     this.endMethod = endMethod;
     this.beginFunc = MethodCallExpressionHelper.GetFunc(metadata, beginMethod, funcCache, locker);
     this.endFunc = MethodCallExpressionHelper.GetFunc(metadata, endMethod, funcCache, locker);
 }
        // Set methodExecutor, returning an error string if there are any problems (ambiguous match, etc.).
        public void DetermineMethodInfo(CodeActivityMetadata metadata, MruCache <MethodInfo, Func <object, object[], object> > funcCache, ReaderWriterLockSlim locker,
                                        ref MethodExecutor methodExecutor)
        {
            bool returnEarly = false;

            MethodExecutor oldMethodExecutor = methodExecutor;

            methodExecutor = null;
            if (string.IsNullOrEmpty(this.MethodName))
            {
                metadata.AddValidationError(SR.ActivityPropertyMustBeSet("MethodName", this.Parent.DisplayName));
                returnEarly = true;
            }

            Type targetType = this.TargetType;

            // If TargetType and the type of TargetObject are both set, it's an error.
            if (targetType != null && this.TargetObject != null && !this.TargetObject.IsEmpty)
            {
                metadata.AddValidationError(SR.TargetTypeAndTargetObjectAreMutuallyExclusive(this.Parent.GetType().Name, this.Parent.DisplayName));
                returnEarly = true;
            }

            // If TargetType was set, look for a static method. If TargetObject was set, look for an instance method. They can't both be set.
            BindingFlags bindingFlags = this.TargetType != null ? staticBindingFlags : instanceBindingFlags;
            string       bindingType  = bindingFlags == staticBindingFlags ? staticString : instanceString;

            if (targetType == null)
            {
                if (this.TargetObject != null && !this.TargetObject.IsEmpty)
                {
                    targetType = this.TargetObject.ArgumentType;
                }
                else
                {
                    metadata.AddValidationError(SR.OneOfTwoPropertiesMustBeSet("TargetObject", "TargetType", this.Parent.GetType().Name, this.Parent.DisplayName));
                    returnEarly = true;
                }
            }

            // We've had one or more constraint violations already
            if (returnEarly)
            {
                return;
            }

            // Convert OutArgs and InOutArgs to out/ref types before resolution
            Type[] parameterTypes =
                Parameters.Select(argument => argument.Direction == ArgumentDirection.In ? argument.ArgumentType : argument.ArgumentType.MakeByRefType())
                .ToArray();

            Type[] genericTypeArguments = this.GenericTypeArguments.ToArray();

            InheritanceAndParamArrayAwareBinder methodBinder = new InheritanceAndParamArrayAwareBinder(targetType, genericTypeArguments, this.Parent);

            // It may be possible to know (and check) the resultType even if the result won't be assigned anywhere.
            // Used 1.) for detecting async pattern, and 2.) to make sure we selected the correct MethodInfo.
            Type resultType = this.ResultType;

            if (this.RunAsynchronously)
            {
                int    formalParamCount          = parameterTypes.Length;
                Type[] beginMethodParameterTypes = new Type[formalParamCount + 2];
                for (int i = 0; i < formalParamCount; i++)
                {
                    beginMethodParameterTypes[i] = parameterTypes[i];
                }
                beginMethodParameterTypes[formalParamCount]     = typeof(AsyncCallback);
                beginMethodParameterTypes[formalParamCount + 1] = typeof(object);

                Type[] endMethodParameterTypes = { typeof(IAsyncResult) };

                this.beginMethod = Resolve(targetType, "Begin" + this.MethodName, bindingFlags,
                                           methodBinder, beginMethodParameterTypes, genericTypeArguments, true);
                if (this.beginMethod != null && !this.beginMethod.ReturnType.Equals(typeof(IAsyncResult)))
                {
                    this.beginMethod = null;
                }
                this.endMethod = Resolve(targetType, "End" + this.MethodName, bindingFlags,
                                         methodBinder, endMethodParameterTypes, genericTypeArguments, true);
                if (this.endMethod != null && resultType != null && !TypeHelper.AreTypesCompatible(this.endMethod.ReturnType, resultType))
                {
                    metadata.AddValidationError(SR.ReturnTypeIncompatible(this.endMethod.ReturnType.Name, MethodName, targetType.Name, this.Parent.DisplayName, resultType.Name));
                    this.endMethod = null;
                    return;
                }

                if (this.beginMethod != null && this.endMethod != null && this.beginMethod.IsStatic == this.endMethod.IsStatic)
                {
                    if (!(oldMethodExecutor is AsyncPatternMethodExecutor) ||
                        !((AsyncPatternMethodExecutor)oldMethodExecutor).IsTheSame(this.beginMethod, this.endMethod))
                    {
                        methodExecutor = new AsyncPatternMethodExecutor(metadata, this.beginMethod, this.endMethod, this.Parent,
                                                                        this.TargetType, this.TargetObject, this.Parameters, this.Result, funcCache, locker);
                    }
                    else
                    {
                        methodExecutor = new AsyncPatternMethodExecutor((AsyncPatternMethodExecutor)oldMethodExecutor,
                                                                        this.TargetType, this.TargetObject, this.Parameters, this.Result);
                    }
                    return;
                }
            }

            MethodInfo result;

            try
            {
                result = Resolve(targetType, this.MethodName, bindingFlags,
                                 methodBinder, parameterTypes, genericTypeArguments, false);
            }
            catch (AmbiguousMatchException)
            {
                metadata.AddValidationError(SR.DuplicateMethodFound(targetType.Name, bindingType, MethodName, this.Parent.DisplayName));
                return;
            }

            if (result == null)
            {
                metadata.AddValidationError(SR.PublicMethodWithMatchingParameterDoesNotExist(targetType.Name, bindingType, MethodName, this.Parent.DisplayName));
                return;
            }
            else if (resultType != null && !TypeHelper.AreTypesCompatible(result.ReturnType, resultType))
            {
                metadata.AddValidationError(
                    SR.ReturnTypeIncompatible(result.ReturnType.Name, MethodName,
                                              targetType.Name, this.Parent.DisplayName, resultType.Name));
                return;
            }
            else
            {
                this.syncMethod = result;
                if (this.RunAsynchronously)
                {
                    if (!(oldMethodExecutor is AsyncWaitCallbackMethodExecutor) ||
                        !((AsyncWaitCallbackMethodExecutor)oldMethodExecutor).IsTheSame(this.syncMethod))
                    {
                        methodExecutor = new AsyncWaitCallbackMethodExecutor(metadata, this.syncMethod, this.Parent,
                                                                             this.TargetType, this.TargetObject, this.Parameters, this.Result, funcCache, locker);
                    }
                    else
                    {
                        methodExecutor = new AsyncWaitCallbackMethodExecutor((AsyncWaitCallbackMethodExecutor)oldMethodExecutor,
                                                                             this.TargetType, this.TargetObject, this.Parameters, this.Result);
                    }
                }
                else if (!(oldMethodExecutor is SyncMethodExecutor) ||
                         !((SyncMethodExecutor)oldMethodExecutor).IsTheSame(this.syncMethod))
                {
                    methodExecutor = new SyncMethodExecutor(metadata, this.syncMethod, this.Parent, this.TargetType,
                                                            this.TargetObject, this.Parameters, this.Result, funcCache, locker);
                }
                else
                {
                    methodExecutor = new SyncMethodExecutor((SyncMethodExecutor)oldMethodExecutor, this.TargetType,
                                                            this.TargetObject, this.Parameters, this.Result);
                }
            }
        }
Exemple #25
0
 public AsyncWaitCallbackMethodExecutor(CodeActivityMetadata metadata, MethodInfo asyncMethod, Activity invokingActivity,
     Type targetType, InArgument targetObject, Collection<Argument> parameters,
     RuntimeArgument returnObject,
      MruCache<MethodInfo, Func<object, object[], object>> funcCache,
     ReaderWriterLockSlim locker)
     : base(invokingActivity, targetType, targetObject, parameters, returnObject)
 {
     Fx.Assert(asyncMethod != null, "Must provide asyncMethod");
     this.asyncMethod = asyncMethod;
     this.asyncFunc = MethodCallExpressionHelper.GetFunc(metadata, asyncMethod, funcCache, locker);
 }