示例#1
0
文件: Program.cs 项目: xxdoc/QuickUSB
        ///////////////////////////////////////
        // The BulkStream completion routine //
        ///////////////////////////////////////
        static void CompletionRoutine(QuickUsb.BulkStream BulkStream)
        {
            // Check for general errors
            if (BulkStream == null)
            {
                Console.WriteLine("BulkStream Error: {0}", QuickUsb.GetLastError());
                return;
            }

            // Note: If we needed to reteive a reference to the managed QuickUsb object
            // associated with this BulkStream object because, for example, the 'qusb'
            // variable was inaccessible to this function, we would do the following:
            //QuickUsb qusb = QuickUsb.RetreiveManagedQuickUsbObject(BulkStream.Handle);

            // Retrieve our user data (the 'tag' in the async function call)
            GCHandle      hTag = GCHandle.FromIntPtr(BulkStream.Tag);
            BulkStreamTag tag  = (BulkStreamTag)hTag.Target;

            // Check for errors
            if (BulkStream.Error != 0)
            {
                Console.WriteLine("--> CR: ERROR! Request #{0} failed with error {1} ({2} of {3} bytes)", tag.Id, BulkStream.Error, BulkStream.BytesTransferred, BulkStream.BytesRequested);
                ++ErrorCount;
            }
            else
            {
                //Console.WriteLine("--> CR: Completed Request #{0} for {1} bytes on thread {2}", tag.Id, BulkStream.BytesTransferred, Thread.CurrentThread.ManagedThreadId);

                //
                // Now that this request has completed we may process the data
                //

                // Retreive a reference to the managed data buffer from the BulkStream.Buffer
                //byte[] buffer = QuickUsb.RetrieveManagedByteDataBuffer(BulkStream.Buffer);
                ushort[] buffer = QuickUsb.RetrieveManagedUShortDataBuffer(BulkStream.Buffer);
                if (buffer == null)
                {
                    Console.WriteLine(String.Format("{0}: ERROR!  Unable to retrieve managed data buffer", DateTime.Now));
                }

                // TODO: Process data
                //Thread.Sleep(50); // Simulate data processing (to force use of more threads)
            }

            // Keep a running count of bytes transferred
            TotalBytes += (int)BulkStream.BytesTransferred;

            // Keep track of the number of oustanding requests
            --RefCount;

            hTag.Free();
        }
示例#2
0
文件: Program.cs 项目: xxdoc/QuickUSB
        ///////////////////////////////////
        // QuickUSB Asynchronous Example //
        ///////////////////////////////////
        static void Main(string[] args)
        {
            // The number of data buffers to use.  An asynchronous data request is issued
            // for each data buffer, then the main thread waits for each request to complete
            // then issues a new asynchrnonous request using the same data buffer as the
            // completed request.  To maximize throughout, the number of buffers should be
            // at least equal to the number of threads (see the SETTING_THREADS setting).
            const int NumBuffers = 8;

            // The byte size of the buffers.  To maximize performance the buffer size should
            // be as large as possible and a power of 2.
            const int BufferByteSize = 512 * 1024; // 512 KB

            // The number of times to issue a request for each buffer.
            const int LOOPS = 50;

            // Variables
            int k, j, Id = 0;

            string[] nameList;
            bool     qResult;

            QuickUsb.Error qusbError;

            // Variables to track time and performace
            long   tStart, tEnd, freq;
            double tElapsed;

            // The data buffers, BulkStream objects, and tag objects.  Because these objects
            // are passed to and used by unmanaged code in QuickUSB land, they must be handled
            // with care.  They cannot be relocated by the garbage collector and must either
            // be pinned or allocated in unmanaged memory.
            ushort[][]            BufferArray = new ushort[NumBuffers][];
            QuickUsb.BulkStream[] BulkStream  = new QuickUsb.BulkStream[NumBuffers];
            BulkStreamTag[]       tag         = new BulkStreamTag[NumBuffers];

            // We must keep an active reference to the delegate so it is not garbage collected.
            // This reference must minimally stay alive until all pending asynchronous requests
            // have completed.
            QuickUsb.BulkStreamCompletionRoutine cbDelegate = new QuickUsb.BulkStreamCompletionRoutine(CompletionRoutine);

            // Query connected modules
            nameList = QuickUsb.FindModules();
            if (nameList.Length == 0)
            {
                Console.WriteLine("No modules found.");
                return;
            }

            // Open the first module
            qusb = new QuickUsb(nameList[0]);
            qusb.Open(nameList[0]);

            // Allocate buffers
            for (k = 0; k < NumBuffers; ++k)
            {
                // Allocate the data buffers in unmanaged memory
                BufferArray[k] = new ushort[BufferByteSize / 2];

                // Allocate the BulkStream objects
                BulkStream[k] = new QuickUsb.BulkStream();

                // Create the tag object as normal.  We will later get a pinned reference to this
                // object to use in issuing the request, that we will later be able to use to
                // reconstruct a reference to the managed tag object in the completion routine.
                // We can do this because the tag data is never accessed or modified in unmanaged
                // land and only ever used in managed land.
                tag[k] = new BulkStreamTag();
            }

            // Start throughput timer
            QueryPerformanceFrequency(out freq);
            QueryPerformanceCounter(out tStart);

            Console.WriteLine("Acquiring data...please wait");

            // Aquire
            for (j = 0; j < (LOOPS + 1); ++j)
            {
                for (k = 0; k < NumBuffers; ++k)
                {
                    // If this is not the first loop, wait for the last transaction to complete
                    if (j != 0)
                    {
                        // Wait for the transaction to complete.  Once this function returns successfully
                        // the completion routine has already been executed and the transaction is
                        // entirely complete.
                        qResult = qusb.BulkWait(BulkStream[k], false);
                        if (!qResult)
                        {
                            qusbError = qusb.LastError();
                            Console.WriteLine("Request failed (QuickUSB Error: {0})", qusb.LastError());
                        }
                        else
                        {
                            // Now that this request has completed we may process the data here or in the
                            // completion routine, though it is better to perform all processing in the
                            // completion routine as they can be multi-threaded, allowing the main thread
                            // to simply issue and re-issue data requests.
                        }
                    }

                    // If this is not the last loop, issue a new transaction
                    if (j != LOOPS)
                    {
                        //Console.WriteLine("Issuing Request #{0}", (Id + 1));

                        // Issue a new transaction
                        tag[k].Id = ++Id;
                        qResult   = qusb.ReadBulkDataAsync(
                            BufferArray[k],
                            BufferByteSize,
                            BulkStream[k],
                            cbDelegate,
                            GCHandle.ToIntPtr(GCHandle.Alloc(tag[k])));

                        if (!qResult)
                        {
                            Console.WriteLine(String.Format("QuickUSB Error: {0}", qusb.LastError()));
                            qusb.Close();
                            return;
                        }
                        else
                        {
                            ++RefCount;
                            ++TransCount;
                        }
                    }
                }
            }

            // Stop the throughput timer
            QueryPerformanceCounter(out tEnd);
            tElapsed = (double)(tEnd - tStart) / (double)(freq);
            Console.WriteLine();

            Console.WriteLine("Time elapsed: {0:0.000} s", tElapsed);
            Console.WriteLine("Total bytes transferred: {0:0.000} MB", ((float)TotalBytes / (1024.0 * 1024.0)));
            Console.WriteLine("Data rate: {0:0.000} MS/s", ((TotalBytes / (1024.0 * 1024.0)) / tElapsed));
            Console.WriteLine();

            // Close the module
            qResult = qusb.Close();
            if (!qResult)
            {
                Console.WriteLine("QuickUSB Error: {0}", qusb.LastError());
                return;
            }

            // Report any leaks or errors
            Console.WriteLine("{0} transaction(s) issued in total", TransCount);
            Console.WriteLine("{0} transaction(s) failed", ErrorCount);
            Console.WriteLine("{0} transaction(s) are still outstanding", RefCount);

            return;
        }