2017-07-14 3 views
-1

Entschuldigung für schlechtes Englisch. In meinem Projekt habe ich zwei Aufgaben. Eine für das Dekodieren von Daten von der IP-Kamera und das Fireframe-bereit-Ereignis für die UI. Und andere, um die Kamera zu sehen, ist nicht offline. Wenn die Kamera offline ist, wird der Fehler-Ereignishandler dem UI-Thread übergeben. UI-Thread-Aufrufmethode Kamera anhalten. Aber die Aufgabe hört nicht auf. Was mache ich falsch?So korrigieren Sie die Aufgabe mit Event Handler

Auf Button klicken Ereignis funktioniert perfekt.

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

Stop-Kamera-Methode:

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

Dies ist meine erste Aufgabe 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" }); 
    } 

Zweite Aufgabe:

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

Antwort

0

Ihre verschachtelte Schleife wird in die Quere . In Ihrer ersten Aufgabe haben Sie, im Wesentlichen:

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

    // some other stuff 

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

Das Problem ist, dass die innere Schleife StopFrameDecoding.Token.ThrowIfCancellationRequested() nie aufruft. Sobald der Code in diese innere Schleife gelangt, überprüft er nie mehr, ob eine Stornierung angefordert wurde.

+0

Hallo, danke für die Antwort. Ich habe es in beide Schleifen gelegt. Funktioniert nicht. Die innere Schleife bricht jedoch ab, wenn das Bildende gefunden wurde, und prüft dann, ob die Löschung ausgelöst und das Bild gestartet wird. –

+0

annullierung arbeitet auf button event hadler –

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