C# Image FIFO === 1. 會從 USB 持續收到 image 資料 2. image 轉成 Array 丟進 FIFO 3. FIFO 出來資料後續經過 DLL 處理 4. bwFIFOin 執行緒, ==不加 sleep 會看到記憶體使用率持續上升!== ```csharp Bitmap bmpImageLoad; byte[] readbmp; Queue<byte[]> FIFO; int FIFOCounter; // 丟資料至 FIFO BackgroundWorker bwFIFOin; // 從 FIFO 拿資料 BackgroundWorker bwFIFOout; public frmTouch() { InitializeComponent(); FIFOCounter = 5; FIFO = new Queue<byte[]>(FIFOCounter); bwFIFOin = new BackgroundWorker(); bwFIFOin.WorkerReportsProgress = true; bwFIFOin.WorkerSupportsCancellation = true; bwFIFOin.DoWork += new DoWorkEventHandler(DoFIFOinWork); bwFIFOin.ProgressChanged += new ProgressChangedEventHandler(DoFIFOinProcessChange); bwFIFOin.RunWorkerCompleted += new RunWorkerCompletedEventHandler(DoFIFOinCompleted); bwFIFOout = new BackgroundWorker(); bwFIFOout.WorkerReportsProgress = true; bwFIFOout.WorkerSupportsCancellation = true; bwFIFOout.DoWork += new DoWorkEventHandler(DoFIFOoutWork); bwFIFOout.ProgressChanged += new ProgressChangedEventHandler(DoFIFOoutProcessChange); bwFIFOout.RunWorkerCompleted += new RunWorkerCompletedEventHandler(DoFIFOoutCompleted); } private void DoFIFOinWork(object sender, DoWorkEventArgs e) { while(true) { //如果不加 sleep 會造記憶體持續上升 Thread.Sleep(1); if (FIFO.Count < FIFOCounter) { FIFO.Enqueue(readbmp); bwFIFOin.ReportProgress((FIFO.Count)); } } } private void DoFIFOinProcessChange(object sender, ProgressChangedEventArgs e) { prgbFIFOCounter.Value = e.ProgressPercentage * (100/ FIFOCounter); } private void DoFIFOinCompleted(object sender, RunWorkerCompletedEventArgs e) { } private void DoFIFOoutWork(object sender, DoWorkEventArgs e) { while (true) { if (FIFO.Count > 0) { FIFO.Dequeue(); // 後續 array 經過影像處理 bwFIFOin.ReportProgress(FIFO.Count); } } } private void DoFIFOoutProcessChange(object sender, ProgressChangedEventArgs e) { prgbFIFOCounter.Value = e.ProgressPercentage * (100 / FIFOCounter); } private void DoFIFOoutCompleted(object sender, RunWorkerCompletedEventArgs e) { } public bool ImageConverterArray(string filePath, out byte[] ReadimageArray, out Bitmap bmpOut) { using (Bitmap bmp = new Bitmap(filePath)) { bmpOut = (Bitmap)bmp.Clone(); BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, PixelFormat.Format24bppRgb); ReadimageArray = new byte[bmpData.Width * bmpData.Height * 3]; Marshal.Copy(bmpData.Scan0, ReadimageArray, 0, ReadimageArray.Length); //複製記憶體區塊 bmp.UnlockBits(bmpData); } return true; } private void BtnSingleCommand_Click(object sender, EventArgs e) { if(readbmp != null) { bwFIFOin.RunWorkerAsync(); bwFIFOout.RunWorkerAsync(); } } private void BtnLoadImage_Click(object sender, EventArgs e) { odlgTouchImageLoad.Filter = "BMP File(*.bmp)|*.bmp"; odlgTouchImageLoad.FileName = ""; //string InitialPath = ""; //if (Directory.Exists(InitialPath)) //{ // odlgTouchImageLoad.InitialDirectory = InitialPath; //} if (odlgTouchImageLoad.ShowDialog() == DialogResult.OK) { string FilePath = odlgTouchImageLoad.FileName; //bmpImageLoad = new Bitmap(FilePath); // 取得 image Array ImageConverterArray(FilePath, out readbmp, out bmpImageLoad); picImageIn.Image = bmpImageLoad; } } ```