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