/// <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 })); } } } }