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;
}
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. –
annullierung arbeitet auf button event hadler –