我有一个C#应用程序,我管理多个IP摄像机。每个摄像头都运行一个任务,该任务执行一系列操作,如启动套接字、流式传输数据和运行对象检测模型。我使用一个字典来管理这些任务,该字典包含摄像机索引及其对应的CancellationTokenSource。
我的问题是,当我更改相机的设置时,我想first
取消该相机的现有任务and then
开始一个新的任务。然而,新任务似乎在旧任务完成清理之前就开始了,这就产生了问题。
下面是示例代码:
摄像头启动任务的主要方法:
internal static Dictionary<int, Tuple<int, CancellationTokenSource>> tokenSources = new Dictionary<int, Tuple<int, CancellationTokenSource>>();
private async Task IPCameraMethod()
{
if (string.IsNullOrWhiteSpace(textBoxUrl.Text) ||
!int.TryParse(SourceComboBox.Name.Replace("comboBox", ""), out int cameraIndex) ||
comboBoxSavedCameras.SelectedIndex < 0)
{
return;
}
string url = textBoxUrl.Text;
int selectedItemIndex = comboBoxSavedCameras.SelectedIndex;
if (tokenSources.TryGetValue(cameraIndex, out var tuple))
{
if (selectedItemIndex != tuple.Item1)
{
tuple.Item2.Cancel();
tuple.Item2.Dispose();
tokenSources.Remove(cameraIndex);
}
}
var newCts = new CancellationTokenSource();
tokenSources[cameraIndex] = Tuple.Create(selectedItemIndex, newCts);
Debug.WriteLine("CREATING NEW TASK");
await Task.Factory.StartNew(() =>
Camera.IPCameraService.Main(SourceImageControl, selectedItemIndex, newCts.Token, url),
newCts.Token,
TaskCreationOptions.DenyChildAttach,
TaskScheduler.Default
);
}
正在调用的任务方法
public async Task Main(System.Windows.Controls.Image imageControl, int cameraIndex, CancellationToken token, string cameraUrl)
{
CameraURLs[cameraIndex] = cameraUrl;
await StartSocket(cameraIndex);
await StartStream(cameraIndex, cameraUrl);
EventHandler(cameraUrl, cameraIndex);
while (!token.IsCancellationRequested)
{
var frame = await RunYolo(cameraIndex);
if (frame != null)
await UpdateDisplay(frame, imageControl);
}
if (token.IsCancellationRequested)
{
Debug.WriteLine("Clearing Websocket!");
var ws = CameraWebsockets[cameraIndex];
if (ws != null && ws.State == System.Net.WebSockets.WebSocketState.Open)
{
await ws.CloseAsync(WebSocketCloseStatus.NormalClosure, "Cancellation requested", CancellationToken.None);
await Task.Delay(500);
}
}
}
问题:我看到的输出是:
CREATING NEW TASK
Clearing Websocket!
我希望看到“清除WebSocket!在“创建新任务”之前。我如何执行这一命令?
尝试:
我尝试使用await等待任务完成,但仍然遇到问题。
任何帮助将不胜感激!
1条答案
按热度按时间u4dcyp6a1#
有几个问题。首先,您的代码使用
Task.Factory.StartNew
作为异步代码,这在99.9%的情况下是错误的。老实说,我很惊讶它的使用频率,因为它是错误的;我经常看到它。正确的替换是Task.Run
。第二,您的代码取消了CTS,但在开始下一个任务之前,它不会
await
旧任务。您的代码应该将任务保存在其数据结构中,然后在开始下一个任务之前对其进行await
。结合这两个: