【发布时间】:2017-07-14 17:16:54
【问题描述】:
抱歉英语不好。在我的项目中,我有两个任务。一种用于解码来自 IP 摄像机的数据并将帧就绪事件发送到 UI。和其他观看相机不离线。 如果相机离线,它会向 UI 线程抛出错误事件处理程序。 UI线程调用方法Stop Camera。但任务并没有停止。我做错了什么?
在按钮点击事件上它的工作完美。
void BtnCamera_Click(object sender, EventArgs e)
{
if (cameraStream.FrameDecoderActive)
{
cameraStream.StopCameraPreview();
}
else
{
Task.Factory.StartNew(() => { cameraStream.StartCameraPreview();});
}
}
停止相机方法:
public void StopCameraPreview()
{
//cancel token source
StopFrameDecoding.Cancel();
StopFrameChecker.Cancel();
}
这是我的第一个任务代码:
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" });
}
第二个任务:
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;
}
【问题讨论】:
标签: c# task cancellationtokensource cancellation-token