private void DoWork()
            {
                foreach (var item in this)
                {
                    item.LastUpdateDateTimeTicks = DateTime.Now.Ticks;
                }

                do
                {
                    try
                    {
                        var dateTimeNow = DateTime.Now.Ticks;
                        foreach (var item in this)
                        {
                            if (item.IsPeriod && (dateTimeNow - item.LastUpdateDateTimeTicks >= item.PeriodTime * 10000))
                            {
                                Debug.WriteLine("Last Period:" + ((dateTimeNow - item.LastUpdateDateTimeTicks) / (double)10000).ToString("N3"));
                                item.LastUpdateDateTimeTicks = dateTimeNow;
                                _sendQueue.Enqueue(item);
                            }
                        }
                    }
                    catch (Exception ex)
                    {
                        Debug.WriteLine("DoWork is now shutdown by Loop Fuction Exception.");
                        _lastException = ex;
                        break;
                    }

                    if (_shutdownEvent.WaitOne(0))
                    {
                        Debug.WriteLine("DoWork is now shutdown!");
                        break;
                    }
                } while (_isRunning);

                _readyToDisposeEvent.Set();

                _isRunning = false;
            }
예제 #2
0
        private void OnReadMessage(IAsyncResult result)
        {
            try
            {
                int?byteOptional = sslStream?.EndRead(result);
                int bytesRead    = byteOptional.HasValue ? byteOptional.Value : 0;

                var content = new byte[bytesRead];
                if (bytesRead == 0)
                {
                    Debug.Log("read bytes of length 0");
                    SocketForceClosed = true;
                    content           = new byte[0];
                    Debug.LogError("Socket closed before Game Over");
                    SyncGameController.Instance.AbortOnNextUpdate();
                    return;
                }
                SocketForceClosed = false;

                content = new byte[bytesRead];
                Array.Copy(currentReadData, content, bytesRead);

                receivePacketsQueue.Enqueue(content);

                currentReadData = new byte[MaxMessageBytes];
                timeoutflag     = 0;

                var state = new System.Object();
                sslStream?.BeginRead(currentReadData, 0, MaxMessageBytes, OnReadMessage, state);
                ResetReadTimer();
            }
            catch (Exception exception)
            {
                // Log as regular message because servers do shut down sometimes
                Debug.Log($"OnReadMessage Exception: {exception}");
            }
        }
예제 #3
0
    public void SafeQueue_int_constructor_works()
    {
        var q = new SafeQueue <string>(5);

        Assert.IsNotNull(q);
        Assert.AreEqual(0, q.Count);
        q.Enqueue("a");
        Assert.AreEqual(1, q.Count);
        q.Enqueue("b");
        Assert.AreEqual(2, q.Count);
        q.Enqueue("c");
        Assert.AreEqual(3, q.Count);
        q.Enqueue("d");
        Assert.AreEqual(4, q.Count);
        q.Enqueue("e");
        Assert.AreEqual(5, q.Count);
        q.Enqueue("f");
        Assert.AreEqual(6, q.Count);
    }
예제 #4
0
    private static void ThreadProc(object state)
    {
        DateTime finish = DateTime.Now.AddSeconds(10);
        Random   rand   = new Random();

        int[] result    = { 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        int   threadNum = (int)state;

        while (DateTime.Now < finish)

        {
            int what = rand.Next(250);
            int how  = rand.Next(100);

            if (how < 16)
            {
                q.Enqueue(what);
                result[(int)ThreadResultIndex.EnqueueCt] += 1;
            }
            else if (how < 32)
            {
                if (q.TryEnqueue(what))
                {
                    result[(int)ThreadResultIndex.TryEnqueueSucceedCt] += 1;
                }
                else
                {
                    result[(int)ThreadResultIndex.TryEnqueueFailCt] += 1;
                }
            }
            else if (how < 48)
            {
                // Even a very small wait significantly increases the success
                // rate of the conditional enqueue operation.
                if (q.TryEnqueue(what, 10))
                {
                    result[(int)ThreadResultIndex.TryEnqueueWaitSucceedCt] += 1;
                }
                else
                {
                    result[(int)ThreadResultIndex.TryEnqueueWaitFailCt] += 1;
                }
            }
            else if (how < 96)
            {
                result[(int)ThreadResultIndex.DequeueCt] += 1;
                try
                {
                    q.Dequeue();
                }
                catch
                {
                    result[(int)ThreadResultIndex.DequeueExCt] += 1;
                }
            }
            else
            {
                result[(int)ThreadResultIndex.RemoveCt]  += 1;
                result[(int)ThreadResultIndex.RemovedCt] += q.Remove(what);
            }
        }

        results[threadNum] = result;

        if (0 == Interlocked.Decrement(ref threadsRunning))
        {
            StringBuilder sb = new StringBuilder(
                "                               Thread 1 Thread 2 Thread 3    Total\n");

            for (int row = 0; row < 9; row++)
            {
                int total = 0;
                sb.Append(titles[row]);

                for (int col = 0; col < 3; col++)
                {
                    sb.Append(String.Format("{0,9}", results[col][row]));
                    total += results[col][row];
                }

                sb.AppendLine(String.Format("{0,9}", total));
            }

            Console.WriteLine(sb.ToString());
        }
    }
예제 #5
0
        private void ReceivePacketsThread(ConnectArgs connectArgs)
        {
            // Thread exceptions are silent, so
            // catching is absolutely required.
            try
            {
                TryOpenTcpSocket(connectArgs);
                TryOpenSslStream();
                TryValidateServer();
                TryHandshake(connectArgs);

                RaiseConnected();

                // Start the send packets thread now that there's a connection
                sendPacketsThread = new Thread(() => { SendPacketsThread(); });
                sendPacketsThread.IsBackground = true;
                sendPacketsThread.Start();

                while (true)
                {
                    byte[] content;
                    if (!ReadPacketBlocking(out content))
                    {
                        break;
                    }

                    receivePacketsQueue.Enqueue(content);
                }
            }
            catch (SocketException exception)
            {
                Debug.Log($"Failed to connect to url={connectArgs.Url} port={connectArgs.Port}\nReason:\n{exception}");
            }
            catch (ThreadInterruptedException)
            {
                // Expected if Disconnect() is called
            }
            catch (ThreadAbortException)
            {
                // Expected if Disconnect() is called
            }
            catch (TimeoutException)
            {
                RaiseReceiveTimedOut();
            }
            catch (Exception exception)
            {
                // something went wrong. probably important.
                Debug.LogError($"Receive packets thread exception:\n{exception}");
                RaiseUnknownError();
            }
            finally
            {
                // The send packets thread might be waiting on ManualResetEvent,
                // interrupt it to ensure that it is stopped.
                sendPacketsThread?.Interrupt();

                // Connect might have failed.
                isConnecting = false;

                sslStream?.Close();
                client?.Close();
            }
        }
예제 #6
0
 /// <summary>
 /// Add a set of arguments to be called by the action roll.
 /// </summary>
 public void Add(IArgs args)
 {
     _argsSet.Enqueue(args);
 }
예제 #7
0
        static void TestQueue()
        {
            Thread[] threads = new Thread[8];
            var queue = new SafeQueue<int>();
            var signal = new AutoResetEvent(false);

            HashSet<int> integers = new HashSet<int>();

            isRunning = true;

            Thread queueReader = new Thread(new ThreadStart(delegate
            {
                while (true)
                {
                    signal.WaitOne();
                    int n;
                    int count = 0;
                    while (queue.Dequeue(out n))
                    {
                        integers.Add(n);
                        count++;
                    }
                    //Console.WriteLine(count);
                    if (!isRunning) return;
                }
            }));

            queueReader.Start();

            Action<int> enqueue = (s) =>
            {
                for (int x = 0; x < 100000; x++)
                {
                    queue.Enqueue(s + x);
                    signal.Set();
                    if (x % 100 == 0) Thread.Yield();
                }
            };

            int start = 0;
            for (int i = 0; i < 8; i++)
            {

                threads[i] = new Thread(new ParameterizedThreadStart((state) => enqueue((int)state)));
                threads[i].Start(start);
                start += 100000;
            }

            for (int i = 0; i < 8; i++)
            {
                threads[i].Join();
            }
            Thread.Yield();
            isRunning = false;
            signal.Set();

            queueReader.Join();

            bool failed = false;
            for (int i = 0; i < 800000; i++)
            {
                if (!integers.Contains(i))
                {
                    //Console.WriteLine("{0} failed", i);
                    failed = true;
                }
            }
            if (failed) Console.WriteLine("Test failed");
        }
예제 #8
0
        static void TestQueue()
        {
            Thread[] threads = new Thread[8];
            var      queue   = new SafeQueue <int>();
            var      signal  = new AutoResetEvent(false);

            HashSet <int> integers = new HashSet <int>();

            isRunning = true;

            Thread queueReader = new Thread(new ThreadStart(delegate
            {
                while (true)
                {
                    signal.WaitOne();
                    int n;
                    int count = 0;
                    while (queue.Dequeue(out n))
                    {
                        integers.Add(n);
                        count++;
                    }
                    //Console.WriteLine(count);
                    if (!isRunning)
                    {
                        return;
                    }
                }
            }));

            queueReader.Start();

            Action <int> enqueue = (s) =>
            {
                for (int x = 0; x < 100000; x++)
                {
                    queue.Enqueue(s + x);
                    signal.Set();
                    if (x % 100 == 0)
                    {
                        Thread.Yield();
                    }
                }
            };

            int start = 0;

            for (int i = 0; i < 8; i++)
            {
                threads[i] = new Thread(new ParameterizedThreadStart((state) => enqueue((int)state)));
                threads[i].Start(start);
                start += 100000;
            }

            for (int i = 0; i < 8; i++)
            {
                threads[i].Join();
            }
            Thread.Yield();
            isRunning = false;
            signal.Set();

            queueReader.Join();

            bool failed = false;

            for (int i = 0; i < 800000; i++)
            {
                if (!integers.Contains(i))
                {
                    //Console.WriteLine("{0} failed", i);
                    failed = true;
                }
            }
            if (failed)
            {
                Console.WriteLine("Test failed");
            }
        }
예제 #9
0
 /// <summary>
 /// Add an action to the task machine with an optional name identifier.
 /// </summary>
 public void Add(string name, Action action, Needle needle = null)
 {
     _ticker.Push();
     _tasks.Enqueue(new Act(new ActionPair(action, new ActionSet <string>(ActionComplete, name)), needle));
 }
예제 #10
0
 /// <summary>
 /// Add an action to be run in the sequence.
 /// </summary>
 public void Add(Action action)
 {
     _queue.Enqueue(new ActionSet(action));
 }
예제 #11
0
 /// <summary>
 /// De-Allocate the given event arg to it can be used for another receive operation
 /// </summary>
 public static void DeallocateForReceive(SocketAsyncEventArgs eventArgs, EventHandler <SocketAsyncEventArgs> ioCompletedHandler)
 {
     eventArgs.Completed -= ioCompletedHandler;
     _eventArgsReceive.Enqueue(eventArgs);
 }