Beispiel #1
0
        void ThreadFunc(object context)
        {
            Queue <byte[]> receivedData = new Queue <byte[]>(BufferList.Length);

            while (true)
            {
                if (Device.Stopping)
                {
                    break;
                }

                try
                {
                    PendingBuffers.Peek().Wait();
                    // Process a large group of received buffers in a batch, if available.
                    int n = 0;
                    try
                    {
                        while (n < BufferList.Length)
                        {
                            QueuedBuffer buf = PendingBuffers.Peek();
                            if (n == 0 || buf.Ready)
                            {
                                byte[] data = Device.EndReadPipe(buf);
                                PendingBuffers.Dequeue();
                                if (data != null)
                                {   // null is a timeout condition.
                                    receivedData.Enqueue(data);
                                }
                                Device.BeginReadPipe(DevicePipeId, buf);
                                // Todo: If this operation fails during normal operation, the buffer is lost from rotation.
                                // Should never happen during normal operation, but should confirm and mitigate if it's possible.
                                PendingBuffers.Enqueue(buf);
                            }
                            n++;
                        }
                    }
                    finally
                    {
                        // Unless we're exiting, ensure we always indicate the data, even if some operation failed.
                        if (!Device.Stopping && receivedData.Count > 0)
                        {
                            lock (this)
                            {
                                foreach (byte[] data in receivedData)
                                {
                                    ReceivedData.Enqueue(data);
                                    QueuedLength  += data.Length;
                                    TotalReceived += data.Length;
                                }
                            }
                            ThreadPool.QueueUserWorkItem(RaiseNewData);
                            receivedData.Clear();
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.Print("Should not happen: Exception in background thread. {0}", ex.ToString());
                    Thread.Sleep(15);
                }

                ReceiveTick.Set();
            }
            Stopped = true;
        }
        void ThreadFunc(object context)
        {
            int recvBytes;

            while (true)
            {
                if (Device.Stopping)
                {
                    break;
                }

                try
                {
                    recvBytes = 0;
                    if (PendingBuffers.Count > 0)
                    {
                        PendingBuffers.Peek().Wait();
                    }
                    // Process a large group of received buffers in a batch, if available.
                    int  n        = 0;
                    bool shortcut = PendingBuffers.Count > 0;
                    try
                    {
                        lock (RequeuePending)
                        {
                            // Requeue buffers that were drained.
                            while (RequeuePending.Count > 0)
                            {
                                QueuedBuffer buf = RequeuePending.Dequeue();
                                Device.BeginReadPipe(DevicePipeId, buf);
                                // Todo: If this operation fails during normal operation, the buffer is lost from rotation.
                                // Should never happen during normal operation, but should confirm and mitigate if it's possible.
                                PendingBuffers.Enqueue(buf);
                            }
                        }
                        if (PendingBuffers.Count == 0)
                        {
                            Thread.Sleep(0);
                        }
                        else
                        {
                            lock (BufferLock)
                            {
                                while (n < BufferList.Length && PendingBuffers.Count > 0)
                                {
                                    QueuedBuffer buf = PendingBuffers.Peek();
                                    if (shortcut || buf.Ready)
                                    {
                                        shortcut = false;
                                        PendingBuffers.Dequeue();
                                        if (Device.EndReadPipe(buf))
                                        {
                                            ReceivedBuffers.Enqueue(buf);
                                            recvBytes += buf.CompletedSize;
                                        }
                                        else
                                        {
                                            // Timeout condition. Requeue.
                                            Device.BeginReadPipe(DevicePipeId, buf);
                                            // Todo: If this operation fails during normal operation, the buffer is lost from rotation.
                                            // Should never happen during normal operation, but should confirm and mitigate if it's possible.
                                            PendingBuffers.Enqueue(buf);
                                        }
                                    }
                                    n++;
                                }
                            }
                        }
                    }
                    finally
                    {
                        // Unless we're exiting, ensure we always indicate the data, even if some operation failed.
                        if (!Device.Stopping && recvBytes > 0)
                        {
                            lock (this)
                            {
                                QueuedLength  += recvBytes;
                                TotalReceived += recvBytes;
                            }
                            ThreadNewData.Set();
                            //ThreadPool.QueueUserWorkItem(RaiseNewData);
                        }
                    }
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Debug.Print("Should not happen: Exception in background thread. {0}", ex.ToString());
                    Thread.Sleep(15);
                }

                ReceiveTick.Set();
            }
            Stopped = true;
        }