コード例 #1
0
ファイル: TaskPool.cs プロジェクト: OSRS/Oncor_OsrsLegacy
        public TaskPoolRunner Next()
        {
            if (this.options.MaxWaitingRequests > System.Threading.Interlocked.Increment(ref this.activeWaiters))
            {
                if (!this.tokenSource.IsCancellationRequested)
                {
                    System.Threading.SpinWait waiter = new System.Threading.SpinWait();
                    while (this.options.MaxActiveWorkers < System.Threading.Interlocked.Increment(ref this.activeWorkers))
                    {
                        System.Threading.Interlocked.Decrement(ref this.activeWorkers); //nope, not yet
                        if (this.tokenSource.IsCancellationRequested)
                        {
                            System.Threading.Interlocked.Decrement(ref this.activeWaiters); //we're leaving, so be nice and stop waiting
                            return(null);
                        }
                        waiter.SpinOnce();
                    }

                    //Note that the while loop incremented the activeWorkers for us, how nice

                    System.Threading.Interlocked.Decrement(ref this.activeWaiters); //we're now a worker
                    return(this.runner);                                            //done -- we still have to decrement active workers in the runner when finished
                }
                //System.Threading.Interlocked.Decrement(ref this.activeWaiters); //we're leaving, so be nice and stop waiting
            }
            System.Threading.Interlocked.Decrement(ref this.activeWaiters);
            return(null); //can't wait because we have too many already waiting
        }
コード例 #2
0
        private static void TestSingle()
        {
            Console.WriteLine("Testing single");
            ServerTaskPoolOptions   opts = new ServerTaskPoolOptions();
            ServerTaskPool <string> pool = new SingleServerTaskPool <string>(new TestServer(), opts);

            Console.WriteLine("Starting");
            pool.Start();
            Console.WriteLine("Started");

            System.Threading.SpinWait w = new System.Threading.SpinWait();
            for (int i = 0; i < 10000; i++)
            {
                w.SpinOnce();
            }

            Console.WriteLine("Stopping");
            pool.Stop();
            Console.WriteLine("Stopped");

            Console.WriteLine("Single Loop Test");
            Console.WriteLine("Total Listened " + listens);
            Console.WriteLine("Total Handled " + handles);
            Console.WriteLine("Testing single End");
        }
コード例 #3
0
ファイル: TaskPool.cs プロジェクト: OSRS/Oncor_OsrsLegacy
        public void Reset()
        {
            lock (this.runner)
            {
                this.activeWaiters = int.MaxValue; //guaranteed to make requests drop on the floor
                if (this.activeWorkers > 0)
                {
                    if (!this.tokenSource.IsCancellationRequested)
                    {
                        try
                        {
                            this.tokenSource.Cancel();
                        }
                        catch
                        { }
                    }
                    System.Threading.SpinWait waiter = new System.Threading.SpinWait();
                    while (this.activeWorkers > 0)
                    {
                        waiter.SpinOnce(); //this is the possible gotcha - we have to be sure all tasks play nicely
                    }
                }

                this.activeWaiters = 0;
                this.tokenSource   = new CancellationTokenSource(true, true);
                this.tokenSource.RegisterCallback(this.runner.Cancel);
                this.runner.NativeToken = new System.Threading.CancellationTokenSource();
                this.runner.Token       = this.tokenSource.Token();
            }
        }
コード例 #4
0
ファイル: Program.cs プロジェクト: jiowchern/Regulus
        private static void Main(string[] args)
        {
            var sw = new SpinWait();
            Program._Enable = true;
            var updater = new Updater();
            var launcher = new Launcher();

            var server = new Server();
            var serverAppliction = new Regulus.Remoting.Soul.Native.Server(server, 12345);

            var client = new Proxy();
            Program.client_UserEvent(client.SpawnUser("user"));

            launcher.Push(serverAppliction);
            updater.Add(client);

            launcher.Launch();
            while(Program._Enable)
            {
                updater.Working();
                sw.SpinOnce();
            }

            updater.Shutdown();
            launcher.Shutdown();

            Console.ReadKey();
        }
コード例 #5
0
        public void SyncInterface(Type serviceType)
        {
            if (!_syncInfoCache.TryGetValue(serviceType, out _syncInfo))
            {
                var conn = ((RpcConnection)_connectionPool.Get());
                conn.OnMessageReceived += (sender, e) =>
                {
                    _binWriter.Seek(0, SeekOrigin.Begin);
                    _stream.Seek(0, SeekOrigin.Begin);

                    _syncInfo = e.MessageData.ToDeserializedObject <ServiceSyncInfo>();
                    _syncInfoCache.AddOrUpdate(serviceType, _syncInfo, (t, info) => _syncInfo);
                    ((IDisposable)sender).Dispose();
                    System.Threading.Interlocked.Exchange(ref _synced, 1);
                };

                conn.Connect();
                _binWriter.Write((int)MessageType.SyncInterface);
                _binWriter.Write(serviceType.FullName);
                conn.Send(_stream.GetBuffer(), (int)_stream.Position, false);
                // todo: rpcclient继承了clientbase的异步方式,而rpc调用天然需要同步方式
                // 后期考虑重构掉这种丑陋的异步模拟同步的方式
                System.Threading.SpinWait spinner = new System.Threading.SpinWait();
                while (_synced == 0)
                {
                    spinner.SpinOnce();
                }
            }
        }
コード例 #6
0
        public static void Dispose(IDisposable caller, ref int callerDisposeState, ref int busyCount, Action <bool> innerDispose)
        {
            if (caller == null)
            {
                throw new ArgumentNullException(nameof(caller));
            }
            if (innerDispose == null)
            {
                throw new ArgumentNullException(nameof(innerDispose));
            }
            if (callerDisposeState == DisposedState)
            {
                return;                                                  //If we are already disposed, do nothing.
            }
            //Wait until there is no work in progress on the object (via EnterBusy/ExitBusy)
            var spinner = new System.Threading.SpinWait();

            while (System.Threading.Interlocked.CompareExchange(ref busyCount, int.MinValue, 0) > 0)
            {
                spinner.SpinOnce();
            }

            // Atomically set our state to 'disposing' but only if it's not already in that state.
            // If it is already in a 'disposing' state, wait for the dispose to complete before
            // returning to the caller.
            while (System.Threading.Interlocked.CompareExchange(ref callerDisposeState, DisposingState, UndisposedState) != UndisposedState)
            {
                if (callerDisposeState == DisposedState)
                {
                    return;                                                      //If someone else completed disposing the object, do nothing.
                }
                spinner.SpinOnce();
            }

            //Need this check in case we're disposed after first check, but before while loop above,
            //in which case we don't enter the loop and the check inside it doesn't get executed.
            if (callerDisposeState == DisposedState)
            {
                return;                                                  //If someone else completed disposing the object, do nothing.
            }
            try
            {
                innerDispose(true);
            }
            finally
            {
                //Call SuppressFinalize in case a derived class adds a finaliser.
                //Ensure it is done in the finally block. We're unlikely to be disposed again,
                //but if we are and we encountered an error last time, we're likely to get the
                //same error again. Worse, we may also get the error when disposed from the
                //finalizer thread, and throwing exceptions there is a bad idea (https://ericlippert.com/2015/05/18/when-everything-you-know-is-wrong-part-one/).
                //Additionally, code in a finally block will also execute if a thread abort
                //occurs on the executing thread.
                GC.SuppressFinalize(caller);

                //Now mark the object as disposed rather than disposing,
                System.Threading.Interlocked.Exchange(ref callerDisposeState, DisposedState);
            }
        }
コード例 #7
0
        private void polldelay(int _delay)
        {
            var spin = new System.Threading.SpinWait();
            while (true)
            {

                spin.SpinOnce();
                if (spin.Count > _delay)
                {
                    break;
                }
            }
        }
コード例 #8
0
ファイル: Program.cs プロジェクト: jiowchern/Regulus
        private static void Main(string[] args)
        {
            var sw = new SpinWait();

            var botCount = 1;
            if(args.Length > 0)
            {
                botCount = int.Parse(args[0]);
            }

            if(args.Length > 1)
            {
                Program.IPAddress = args[1];
            }

            var clientHandler = new ClientHandler(Program.IPAddress, Program.Port, botCount);
            var view = new ConsoleViewer();
            Singleton<Log>.Instance.Initial(view);
            var input = new ConsoleInput(view);
            var client = new Client(view, input);
            var packetRegulator = new PacketRegulator();
            client.Command.Register(
                "si",
                () =>
                {
                    Console.WriteLine(
                        "Send Interval : {0}\nRequest Package Queue : {1}",
                        HitHandler.Interval,
                        packetRegulator.Sampling);
                });
            client.ModeSelectorEvent += clientHandler.Begin;

            var updater = new Updater();
            updater.Add(client);
            updater.Add(clientHandler);
            updater.Add(packetRegulator);

            while(client.Enable)
            {
                input.Update();
                updater.Working();
                sw.SpinOnce();
            }

            client.Command.Unregister("si");
            updater.Shutdown();
            clientHandler.End();
            Singleton<Log>.Instance.Final();
        }
コード例 #9
0
ファイル: RuntimeUtils.cs プロジェクト: OSRS/Oncor_OsrsLegacy
        public static void WaitForInitializableState(IStatefulExecution state, bool allowFailed)
        {
            MethodContract.NotNull(state, nameof(state));

            System.Threading.SpinWait waiter = new System.Threading.SpinWait();
            while (true)
            {
                if (Initializable(state.State, allowFailed))
                {
                    return;
                }
                if (allowFailed && Failed(state.State))
                {
                    return; //try to allow a recovery here
                }
                waiter.SpinOnce();
            }
        }
コード例 #10
0
ファイル: HandoffEvent.cs プロジェクト: OSRS/Oncor_OsrsLegacy
        public void Handle()
        {
            try
            {
                T data;

                if (!this.data.TryDequeue(out data))
                {
                    System.Threading.SpinWait waiter = new System.Threading.SpinWait();
                    do
                    {
                        if (!this.Token.IsCancellationRequested)
                        {
                            waiter.SpinOnce(); //backs off on the wait rather than just tight spin
                        }
                        else
                        {
                            break; //we're cancelled
                        }
                    }while (!this.data.TryDequeue(out data));
                }

                try
                {
                    if (!this.Token.IsCancellationRequested)
                    {
                        this.handle(data);
                    }
                }
                catch
                { }
                finally
                {
                    System.Threading.Interlocked.Decrement(ref this.currentQueueSize); //can't forget to pull us out of the contention
                }
            }
            catch (Exception e)                                                                    //we could in theory get to an bad place where we actually dequeued but didn't decrement since we caught
            {
                System.Threading.Interlocked.Exchange(ref this.currentQueueSize, this.data.Count); //this might be sketchy as well if the queue size changes during the call to Count
            }
        }
コード例 #11
0
        public List <Suit> Find(PropertyValue[] filter_propertys, int out_amount)
        {
            object      suitSetLock = new object();
            List <Suit> suitSet     = new List <Suit>();


            var rangePartitioner = System.Collections.Concurrent.Partitioner.Create(0, _Total());

            object readLock = new object();
            int    reads    = 0;

            System.Threading.SpinWait sw = new System.Threading.SpinWait();
            Parallel.ForEach(rangePartitioner, (range, loopState) =>
            {
                Regulus.Utility.TimeCounter time = new Regulus.Utility.TimeCounter();
                List <Suit> suits = new List <Suit>();
                int count         = 0;
                //var range = new {Item1 = 0 , Item2 = _Total()};
                for (long i = range.Item2 - 1; i >= range.Item1; --i, ++count)
                {
                    int[] indexs = _GetIndexs(i);
                    var s        = new Suit(
                        _GetCard(0, indexs[0]),
                        _GetCard(1, indexs[1]),
                        _GetCard(2, indexs[2]),
                        _GetCard(3, indexs[3]),
                        _GetCard(4, indexs[4]),
                        _GetCard(5, indexs[5]),
                        _GetCard(6, indexs[6]),
                        _GetCard(7, indexs[7]));

                    bool pass = (from filter in filter_propertys
                                 where s.GetValue(filter) < filter.Value
                                 select false).Count() == 0;
                    sw.SpinOnce();
                    if (pass)
                    {
                        suits.Add(s);
                    }

                    if (time.Second > 1)
                    {
                        lock (readLock)
                        {
                            reads += count;
                            count  = 0;
                        }

                        _UpdateSet(ref suitSet, filter_propertys, out_amount, suitSetLock, reads, suits);
                        suits.Clear();
                        time.Reset();

                        sw.SpinOnce();
                    }
                }

                lock (readLock)
                {
                    reads += count;
                    count  = 0;
                }
                _UpdateSet(ref suitSet, filter_propertys, out_amount, suitSetLock, reads, suits);
            });



            var result = suitSet.OrderByDescending((suit) => suit.GetValue(filter_propertys[0]));

            foreach (var property in filter_propertys.Skip(1))
            {
                result = result.ThenByDescending((suit) => suit.GetValue(property));
            }

            return(result.ToList());
        }
コード例 #12
0
        public string DynamicPopulateMethod()
        {
            String message = "";
            AnswerApp.Models.AnswerAppDataContext db = new AnswerApp.Models.AnswerAppDataContext();

            AnswerApp.Models.User thisUser = db.Users.Single(d => d.UserName.Equals(User.Identity.Name));

            System.Threading.SpinWait sw = new System.Threading.SpinWait();
            //string knownCategoryValues;
            //System.Threading.SpinWait.SpinUntil(thisUser.MetaData.EndsWith("ready"), 1000);
            //while (!thisUser.MetaData.EndsWith("ready")) { sw.SpinOnce(); }
            //if (!thisUser.MetaData.EndsWith("ready")) { sw.SpinOnce(); }//return null; }
            //thisUser.MetaData = thisUser.MetaData.Replace("ready", "");
            string knownCategoryValues = thisUser.MetaData;

            db.SubmitChanges();

            StringDictionary incomingKnownCatagories = CascadingDropDown.ParseKnownCategoryValuesString(knownCategoryValues);

            SelectModel theUsersSelection = new SelectModel(incomingKnownCatagories["textbook"] + "_" + incomingKnownCatagories["unit"] + "_" + incomingKnownCatagories["chapter"] + "_" + incomingKnownCatagories["section"] + "_" + incomingKnownCatagories["page"] + "_" + incomingKnownCatagories["question"]);
            String Textbook_Title = theUsersSelection.Textbook;
            String Unit_Title = theUsersSelection.Unit;
            String Chapter_Title = theUsersSelection.Chapter;
            String Section_Title = theUsersSelection.Section;
            String Page_Number = theUsersSelection.Page;
            String Question_Number = theUsersSelection.Question;

            //Populate parent groupings based on child groupings
            if (!Question_Number.Equals("All") && Page_Number.Equals("All"))
            {
                IQueryable<AnswerApp.Models.Question> retrieved;
                Question[] results;
                //Find all questions from the selected section
                retrieved = from theAnswers in db.Questions
                            where theAnswers.Textbook_Title.Equals(Textbook_Title)
                            && theAnswers.Section_Title.Equals(Section_Title)
                            && theAnswers.Question_Number.Equals(Question_Number)
                            select theAnswers;
                results = retrieved.ToArray<Question>();
                //If there are no questions of this number from the selected section
                if (results.Length < 1)
                {
                    //Find all questions from the selected chapter
                    retrieved = from theAnswers in db.Questions
                                where theAnswers.Textbook_Title.Equals(Textbook_Title)
                                && theAnswers.Chapter_Title.Equals(Chapter_Title)
                                && theAnswers.Question_Number.Equals(Question_Number)
                                select theAnswers;
                    results = retrieved.ToArray<Question>();
                    //If there are no questions of this number from the selected chapter
                    if (results.Length < 1)
                    {
                        //Find all questions from the selected unit
                        retrieved = from theAnswers in db.Questions
                                    where theAnswers.Textbook_Title.Equals(Textbook_Title)
                                    && theAnswers.Unit_Title.Equals(Unit_Title)
                                    && theAnswers.Question_Number.Equals(Question_Number)
                                    select theAnswers;
                        results = retrieved.ToArray<Question>();
                        //If there are no questions of this number from the selected unit
                        if (results.Length < 1)
                        {
                            //Find all questions from the selected textbook
                            retrieved = from theAnswers in db.Questions
                                        where theAnswers.Textbook_Title.Equals(Textbook_Title)
                                        && theAnswers.Textbook_Title.Equals(Textbook_Title)
                                        && theAnswers.Question_Number.Equals(Question_Number)
                                        select theAnswers;
                            results = retrieved.ToArray<Question>();
                        }
                    }
                }
                if (results.Length > 1)
                {
                    return "<span style=\"color:red;\">There are multiple Questions with that number.  Please make a more specific selection.</span>";
                }
                else if (results.Length == 1)
                {
                    Page_Number = results.First().Page_Number;
                    Section_Title = results.First().Section_Title;
                    Chapter_Title = results.First().Chapter_Title;
                    Unit_Title = results.First().Unit_Title;
                }
                else if (results.Length == 0)
                {
                    return "<span style=\"color:red;\">Error: The selected Question could not be found.  Please contact the Solvation.ca developement team.  " + knownCategoryValues + "</span>";

                }
            }
            if (!Page_Number.Equals("All") && Section_Title.Equals("All"))
            {
                //Section_Title = db.Pages.Single<Page>(p => p.Page_Number.Equals(Page_Number)).Section_Title;
                IQueryable<AnswerApp.Models.Page> retrieved = null;
                retrieved = from theAnswers in db.Pages
                            where theAnswers.Textbook_Title.Equals(Textbook_Title)
                            && theAnswers.Page_Number.Equals(Page_Number)
                            select theAnswers;
                Section_Title = retrieved.First().Section_Title;// db.Pages.Single<Page>(s => s.Page_Title.Equals(Page_Title)).Section_Title;
            }
            if (!Section_Title.Equals("All") && Chapter_Title.Equals("All"))
            {
                IQueryable<AnswerApp.Models.Section> retrieved = null;
                retrieved = from theAnswers in db.Sections
                            where theAnswers.Textbook_Title.Equals(Textbook_Title)
                            && theAnswers.Section_Title.Equals(Section_Title)
                            select theAnswers;
                Chapter_Title = retrieved.First().Chapter_Title;// db.Sections.Single<Section>(s => s.Section_Title.Equals(Section_Title)).Chapter_Title;
            }
            if (!Chapter_Title.Equals("All") && Unit_Title.Equals("All"))
            {
                //Unit_Title = db.Chapters.Single<Chapter>(c => c.Chapter_Title.Equals(Chapter_Title)).Unit_Title;
                IQueryable<AnswerApp.Models.Chapter> retrieved = null;
                retrieved = from theAnswers in db.Chapters
                            where theAnswers.Textbook_Title.Equals(Textbook_Title)
                            && theAnswers.Chapter_Title.Equals(Chapter_Title)
                            select theAnswers;
                Unit_Title = retrieved.First().Unit_Title;// db.Chapters.Single<Chapter>(s => s.Chapter_Title.Equals(Chapter_Title)).Unit_Title;
            }
            if (Textbook_Title.Equals("Select a Textbook"))
            {
                return "Please make a selection";
            }
            if (Textbook_Title.Equals(""))
            {
                return "Please Select a textbook";
            }

            theUsersSelection.Textbook = Textbook_Title;
            theUsersSelection.Unit = Unit_Title;
            theUsersSelection.Chapter = Chapter_Title;
            theUsersSelection.Section = Section_Title;
            theUsersSelection.Page = Page_Number;
            theUsersSelection.Question = Question_Number;

            AnswerApp.Controllers.AnswersController theAnswerController = new AnswerApp.Controllers.AnswersController();
            int NumberOfSolutionsToPurchase = theAnswerController.NumberOfQuestions(theUsersSelection, db);
            double TotalValue = (NumberOfSolutionsToPurchase * AnswerApp.Controllers.AnswersController.PriceOfSingleSolution);

            int NumberOfSolutionsForThisUser = 0;
            int NumberSelectedUserAlreadyHas = 0;
            String[] UserAnswers;
            if (thisUser.Answers != null)
            {
                UserAnswers = thisUser.Answers.Split(new char[1] { ';' });
                foreach (String theAnswer in UserAnswers)
                {
                    SelectModel currentAnswer = new SelectModel(theAnswer);
                    int NumberOfSolutionsInCurrentAnswer = theAnswerController.NumberOfQuestions(currentAnswer, db);
                    NumberOfSolutionsForThisUser += NumberOfSolutionsInCurrentAnswer;
                    if (theUsersSelection.Contains(currentAnswer))
                    {
                        NumberSelectedUserAlreadyHas += NumberOfSolutionsInCurrentAnswer;
                    }
                }
            }
            int SolutionsRemainingToBePurchased = (NumberOfSolutionsToPurchase - NumberSelectedUserAlreadyHas);
            int TotalRemainingSolutions = SolutionsRemainingToBePurchased - thisUser.Credit;

            if(SolutionsRemainingToBePurchased > 1)
            {
                if (NumberOfSolutionsForThisUser > 1)
                { message += "You have seleted " + NumberOfSolutionsToPurchase + " solutions.  "; }
                else
                { message += "You have seleted " + NumberOfSolutionsToPurchase + " solution.  "; }
                message += SolutionsRemainingToBePurchased + " are new.  ";
                if (TotalRemainingSolutions >= 1)
                {
                    if (thisUser.Credit > 1)
                    { message += "You have " + thisUser.Credit + " credits, the remaining " + TotalRemainingSolutions + " will need to be purchased."; }
                    else
                    { message += "You have " + thisUser.Credit + " credit, the remaining " + TotalRemainingSolutions + " will need to be purchased."; }
                }
                else
                {
                    if (thisUser.Credit > 1)
                    { message += "You have " + thisUser.Credit + " credits.  "; }
                    else
                    { message += "You have " + thisUser.Credit + " credit.  "; }
                }
            }
            else if(SolutionsRemainingToBePurchased == 1)
            {
                if (NumberOfSolutionsForThisUser > 1)
                { message += "You have seleted " + NumberOfSolutionsToPurchase + " solutions.  "; }
                else
                { message += "You have seleted " + NumberOfSolutionsToPurchase + " solution.  "; }
                message += SolutionsRemainingToBePurchased + " is new.  ";
                if (TotalRemainingSolutions >= 1)
                {
                    if (thisUser.Credit > 1)
                    { message += "You have " + thisUser.Credit + " credits, the remaining " + TotalRemainingSolutions + " will need to be purchased."; }
                    else
                    { message += "You have " + thisUser.Credit + " credit, the remaining " + TotalRemainingSolutions + " will need to be purchased."; }

                }
                else
                {
                    if (thisUser.Credit > 1)
                    { message += "You have " + thisUser.Credit + " credits.  "; }
                    else
                    { message += "You have " + thisUser.Credit + " credit.  "; }
                }
            }
            else//if(SolutionsRemainingToBePurchased <= 1)
            {
                return "You presently have access to all of the selected solutions";
            }

            return message;

            return theUsersSelection.Textbook + "_" + theUsersSelection.Unit + "_" + theUsersSelection.Chapter + "_" + theUsersSelection.Section + "_" + theUsersSelection.Page + "_" + theUsersSelection.Question;

            //return theModel.Textbook + "_" + theModel.Unit + "_" + theModel.Chapter + "_" + theModel.Section + "_" + theModel.Page + "_" + theModel.Question;
        }
コード例 #13
0
        public object[] InvokeMethod(string metaData, params object[] parameters)
        {
            //prevent call to invoke method on more than one thread at a time
            lock (_syncRoot)
            {
                var mdata = metaData.Split('|');

                //find the matching server side method ident
                var ident = -1;
                for (int index = 0; index < _syncInfo.MethodInfos.Length; index++)
                {
                    var si = _syncInfo.MethodInfos[index];
                    //first of all the method names must match
                    if (si.MethodName == mdata[0])
                    {
                        //second of all the parameter types and -count must match
                        if (mdata.Length - 1 == si.ParameterTypes.Length)
                        {
                            var matchingParameterTypes = true;
                            for (int i = 0; i < si.ParameterTypes.Length; i++)
                            {
                                if (!mdata[i + 1].Equals(si.ParameterTypes[i].FullName))
                                {
                                    matchingParameterTypes = false;
                                    break;
                                }
                            }
                            if (matchingParameterTypes)
                            {
                                ident = si.MethodIdent;
                                break;
                            }
                        }
                    }
                }

                if (ident < 0)
                {
                    throw new Exception(string.Format("Cannot match method '{0}' to its server side equivalent", mdata[0]));
                }

                var conn = ((RpcConnection)_connectionPool.Get());
                conn.OnMessageReceived += (sender, e) =>
                {
                    _binWriter.Seek(0, SeekOrigin.Begin);
                    _stream.Seek(0, SeekOrigin.Begin);

                    using (MemoryStream stream = new MemoryStream(e.MessageData))
                        using (BinaryReader br = new BinaryReader(stream))
                        {
                            // Read the result of the invocation.
                            MessageType messageType = (MessageType)br.ReadInt32();
                            if (messageType == MessageType.UnknownMethod)
                            {
                                throw new Exception("Unknown method.");
                            }

                            outParams = _parameterTransferHelper.ReceiveParameters(br);

                            if (messageType == MessageType.ThrowException)
                            {
                                throw (Exception)outParams[0];
                            }

                            System.Threading.Interlocked.Exchange(ref _received, 1);
                        }
                };

                conn.Connect();
                // write the message type
                _binWriter.Write((int)MessageType.MethodInvocation);
                // write service key index
                _binWriter.Write(_syncInfo.ServiceKeyIndex);
                // write the method ident to the server
                _binWriter.Write(ident);
                // send the parameters
                _parameterTransferHelper.SendParameters(_syncInfo.UseCompression,
                                                        _syncInfo.CompressionThreshold,
                                                        _binWriter,
                                                        parameters);

                conn.Send(_stream.GetBuffer(), (int)_stream.Position, false);

                // todo: rpcclient继承了clientbase的异步方式,而rpc调用天然需要同步方式
                // 后期考虑重构掉这种丑陋的异步模拟同步的方式
                System.Threading.SpinWait spinner = new System.Threading.SpinWait();
                while (_received == 0)
                {
                    spinner.SpinOnce();
                }

                return(outParams);
            }
        }