-1

Sorry for bad english. In my project i have two Task. One for decoding data from IP camera and fire frame ready event to UI. And other to watch the camera is not offline. If the camera is offline, it throw Error event handler to UI thread. UI thread call method Stop Camera. But Task not stop. What am i doing wrong?

On Button click event its working perfect.

        void BtnCamera_Click(object sender, EventArgs e)
    {
        if (cameraStream.FrameDecoderActive)
        {
            cameraStream.StopCameraPreview();
        }
        else
        {
            Task.Factory.StartNew(() => { cameraStream.StartCameraPreview();});
        }
    }

Stop Camera method:

public void StopCameraPreview()
  {
   //cancel token source
   StopFrameDecoding.Cancel();
   StopFrameChecker.Cancel();
 }

This is my first task code:

private void Run(Stream cameraStream)
    {
        try
        {
            FrameDecoderActive = true;
            //inicializacija
            Extensions Extensions = new Extensions();
            BinaryReader streamReader = new BinaryReader(cameraStream);
            byte[] imageBuffer = new byte[1024 * 1024];
            byte[] curentBuffer = streamReader.ReadBytes(readSize);

            //kadru skaitymas
            while (FrameDecoderActive)
            {
                StopFrameDecoding.Token.ThrowIfCancellationRequested();
                int imageStart = Extensions.Find(curentBuffer, jpegHeader);
                if (imageStart != -1)
                {
                    //randa jpg pradžia kameros streme
                    int size = curentBuffer.Length - imageStart;

                    //copy nuo jpg pradžio iki buferio galo į image buferį
                    Array.Copy(curentBuffer, imageStart, imageBuffer, 0, size);

                    //skaito kadrus kol gauna cancel tokeną
                    while (FrameDecoderActive)
                    {
                        curentBuffer = streamReader.ReadBytes(readSize);
                        int imageEnd = Extensions.Find(curentBuffer, boundaryBytes);

                        //jeigu neranda jpg pabaigos nuskaitytame buferyje
                        if (imageEnd != -1)
                        {
                            Array.Copy(curentBuffer, 0, imageBuffer, size, imageEnd);
                            size += imageEnd;

                            //naujas kadras
                            byte[] frame = new byte[size];
                            Array.Copy(imageBuffer, 0, frame, 0, size);
                            LastFrameTime = DateTime.Now;
                            if (!FrameCheckerActive)
                            {
                                StopFrameChecker = new CancellationTokenSource();
                                Task.Factory.StartNew(() => { FrameChecker(); }, StopFrameChecker.Token);
                            }
                            FrameReady.Invoke(this, new FrameReadyEventArgs { FrameBuffer = frame, Bitmap = BitmapFactory.DecodeByteArray(frame, 0, frame.Length) });

                            //kopijuojam buferio likuti i buferio pradzia
                            Array.Copy(curentBuffer, imageEnd, curentBuffer, 0, curentBuffer.Length - imageEnd);
                            //uzpildom likusia tuscia vieta
                            byte[] temp = streamReader.ReadBytes(imageEnd);
                            Array.Copy(temp, 0, curentBuffer, curentBuffer.Length - imageEnd, temp.Length);
                            break;
                        }

                        Array.Copy(curentBuffer, 0, imageBuffer, size, curentBuffer.Length);
                        size += curentBuffer.Length;
                    }
                }
            }
        }
        catch (OperationCanceledException)
            {
                Error.Invoke(this, new ErrorEventArgs { ErrorCode = 101, Message = "Camera decoder Canceled" });
            }
        catch (Exception ex)
            {
                Error.Invoke(this, new ErrorEventArgs { ErrorCode = 999, Message = ex.Message });
            }
        cameraStream.Close();
        FrameDecoderActive = false;
        Error.Invoke(this, new ErrorEventArgs { ErrorCode = 0, Message = "Camera Stoped" });
    }

Second Task :

private async void FrameChecker()
    {
        FrameCheckerActive = true;
        await Task.Delay(1000);
        try
        {
            while (FrameDecoderActive)
            {
                StopFrameChecker.Token.ThrowIfCancellationRequested();
                DateTime curentTime = DateTime.Now;
                var dif = curentTime - LastFrameTime;
                if (dif.Seconds > 2)
                {
                    throw new TimeoutException("Camera Frame timeout");
                }
                await Task.Delay(1000);
            }
        }
        catch (TimeoutException)
        {
            Error.Invoke(this, new ErrorEventArgs { ErrorCode = 100, Message = "Camera Frame Timeout" });
        }
        catch (OperationCanceledException)
        {
            Error.Invoke(this, new ErrorEventArgs { ErrorCode = 101, Message = "Frame Checker Canceled"});
        }
        catch (Exception ex)
        {
            Error.Invoke(this, new ErrorEventArgs { ErrorCode = 999, Message = ex.Message});
        }
        FrameCheckerActive = false;
    }
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291

2 Answers2

0

Your nested loop is getting in the way. In your first task you have, essentially:

while (FrameDecoderActive)
{
    StopFrameDecoding.Token.ThrowIfCancellationRequested();

    // some other stuff

    while (FrameDecoderActive)
    {
        // more stuff
        // never checks for cancellation!
    }
}

The problem is that the inner loop never calls StopFrameDecoding.Token.ThrowIfCancellationRequested(). So once the code gets into that inner loop, it never again checks to see if cancellation was requested.

Jim Mischel
  • 131,090
  • 20
  • 188
  • 351
  • Hi, thanks for the reply. I put it in both loops. Not working. But inner loop break when image end found and then check if cancelation thrown and searching image start. – Benas Laurinaitis Jul 14 '17 at 18:47
0
   while (FrameDecoderActive)
   {
   //checking if cacelation thrown
   StopFrameDecoding.Token.ThrowIfCancellationRequested();

  //Search image start on buffer readed from camera stream


   while (FrameDecoderActive)
   {
  // read while found image end then break
   }
   }