示例#1
0
        /// <summary>
        /// Invokes the method
        /// </summary>
        /// <param name="request">The Request object to pass to the Method</param>
        /// <param name="reply">The Reply to the client</param>
        internal void Invoke(Request request, Reply reply)
        {
            bool   invoke     = true;
            Binary resultKey  = null;
            string cachingKey = null;

            if (IsResultCacheable)
            {
                resultKey  = request.ParameterSet.GetHash();
                cachingKey = string.Format(CACHING_KEY_FORMAT, _id, resultKey);

                CachedResult cachedResult = ResultCache.GetCachedResult(_id, resultKey);
                if (cachedResult.Found)
                {
                    if (cachedResult.IsExpired && !Monitor.IsEntered(DynamicLock.Get(CACHING_LOCK_TYPE, cachingKey)))
                    {
                        request.MakeThreadSafe();

                        ParameterizedThreadStart work = new ParameterizedThreadStart(CacheMethodCall);
                        Thread thread = new Thread(work);

                        thread.Start(new CacheMethodCallParams()
                        {
                            Method    = this,
                            ResultKey = resultKey,
                            Request   = request,
                            Reply     = new Reply(request.FormatKey)
                        });
                    }

                    reply.Result.Raw.InnerXml = cachedResult.Result.GetInnerXml();

                    XmlElement xCached = reply.Response.AddElement(Settings.GetString("NodeNameCachedResult"));
                    xCached.SetAttribute(Settings.GetString("NodeAttributeCachedResultUpdatedOn"), Settings.FormatDateTime(cachedResult.UpdatedOn));
                    xCached.SetAttribute(Settings.GetString("NodeAttributeCachedResultExpiresOn"), Settings.FormatDateTime(cachedResult.ExpiresOn));

                    invoke = false;
                }
                else
                {
                    //if the current result is caching, sleep
                    while (Monitor.IsEntered(DynamicLock.Get(CACHING_LOCK_TYPE, cachingKey)))
                    {
                        Thread.Sleep(Settings.GetInt("ResultCachingConcurrentCallSleepInterval"));
                    }

                    cachedResult = ResultCache.GetCachedResult(_id, resultKey);
                    if (cachedResult.Found)
                    {
                        reply.Result.Raw.InnerXml = cachedResult.Result.GetInnerXml();

                        XmlElement xCached = reply.Response.AddElement(Settings.GetString("NodeNameCachedResult"));
                        xCached.SetAttribute(Settings.GetString("NodeAttributeCachedResultUpdatedOn"), Settings.FormatDateTime(cachedResult.UpdatedOn));
                        xCached.SetAttribute(Settings.GetString("NodeAttributeCachedResultExpiresOn"), Settings.FormatDateTime(cachedResult.ExpiresOn));

                        invoke = false;
                    }
                }
            }

            if (invoke)
            {
                if (SPECIAL_METHODS.ContainsKey(_key))
                {
                    InvokeSpecialMethod(reply.Result);
                }
                else
                {
                    if (IsResultCacheable)
                    {
                        request.MakeThreadSafe();

                        CacheMethodCall(new CacheMethodCallParams()
                        {
                            Method     = this,
                            ResultKey  = resultKey,
                            CachingKey = cachingKey,
                            Request    = request,
                            Reply      = reply
                        });
                    }
                    else
                    {
                        _mi.Invoke(null, (new object[] { request, reply.Result, reply.Error }));
                    }
                }
            }
        }