---
# System prepended metadata

title: C# Image FIFO

---

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;
            }

        }
```