C# 取消订阅套接字流后取消特定子线程或任务
我正在尝试使用以下代码在主任务下运行多线程任务,但没有达到预期效果C# 取消订阅套接字流后取消特定子线程或任务,c#,multithreading,websocket,task,C#,Multithreading,Websocket,Task,我正在尝试使用以下代码在主任务下运行多线程任务,但没有达到预期效果 CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(); CancellationToken cancellationToken = cancellationTokenSource.Token; using (var socketClient = new SocketClient()) { Task.Factory.St
CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;
using (var socketClient = new SocketClient()) {
Task.Factory.StartNew(() => {
Console.WriteLine("Starting child task...");
if (cancellationToken.IsCancellationRequested) {
Console.WriteLine("Task cancellation requested");
throw new OperationCanceledException(cancellationToken);
}
List<string> pairsList = db.GetPairsList(); //loads from db and it's dynamic
try {
// loop through each pair
Parallel.ForEach(pairsList, pair => {
Console.WriteLine("Item {0} has {1} characters", pair, pair.Length);
SubscribeToStream(socketClient);//I'm subscribing to some socket streams
});
} catch (OperationCanceledException ex) {
Console.WriteLine(ex.Message);
}
}, cancellationToken);
}
我想运行一个主任务,它分别保存子任务。启动按钮将启动主线程,停止按钮将与主线程一起安全停止所有线程
每个子线程都订阅了一些为每对线程运行的套接字流。如果找到匹配的数据,则我将从对列表中删除该对,但由于流订阅或线程可能未成功取消,线程将继续。但是,我可以取消主线程,但我希望取消特定的线程/任务,而不是主任务,并允许主任务与现有或新添加的线程对一起继续
我们如何才能安全地实现此场景?对于每个要取消的线程/任务,您需要将cancellationToken转发给它并反复检查。因此,您需要确保内部任务(在Parallel.ForEach循环中)也会重复检查cancellationToken,并在触发时中止
提示:最好始终保留对已创建任务的引用,以便能够检查它是否真的结束了。因此,保留对Factory.StartNew()返回值的引用,并在以后使用它检查任务是否真的结束了 你能提供一些粗略的示例代码来理解你的案例吗?我指的是根据上述情况的最佳解决方案,这并不容易,因为我不知道你们在你们的内部循环中做了什么。是有一个循环在那里,还是你在等待回调?让多个任务等待同一个线程对我来说也有点奇怪。我的主任务包含多个独立的子任务。主任务始终保持活动状态,在完成任何子任务时,该特定任务应取消,而其他任务应保持不变。现在,你让我困惑了:为什么要在任务完成后取消它?如果要在任务正常终止之前中止任务,则需要取消。如果让任务一直运行到最后,它将终止。如果任务本身知道它已经完成了,你不需要任何复杂的逻辑,你可以退出这个函数。原因是我在每个任务下都有套接字流,即使任务完成后也不会取消订阅。
private void SubscribeToStream(string pair, SocketClient socketClient) {
var subscribePair = socketClient.SubscribeToPair(pair, data => {
//here socket stream returns callback each second for each pair
Application.Current.Dispatcher.Invoke(() => {
//if perfect match found then Remove pair from the list
if(a == b) {
db.removePair(pair);
}
//after removing refresh new pairs list to see if new pair added or removed from the main list from db..
}
//after match, we need to unsubscribe from the current pair
socketClient.UnsubscribeFromPair(subscribePair.Data);
//IT CALLS SAME PAIR AGAIN EVEN AFTER UNSUBSCRIBING FROM SOCKET STREAM
}
}