只有在任务处于完成状态(RanToCompletion、Faulted 或 Canceled)时才能释放它

stevenjin 2020-06-08 11:44:07
在检测到连接失败时,想终止所有任务,包括20毫秒触发一次的定时器,我用了下面这个代码,但报错。
有什么好的办法终止有所线程吗?

foreach (Task t in tasks) {
if (t != null) {
t.Wait(100);
t.Dispose();
}
}
...全文
5322 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
一般来说,稍微复杂一点点儿的程序,任务的控制应该可以独立出来,一定是每一个独立任务对应一个业务数据结构,这个结构对象也可以持久化(例如写到日志中)。你可以把信号定义为业务控制对象的属性,在任务中去检测纯业务上的(而不是编程语言的)信号判断出场。
  • 打赏
  • 举报
回复
使用“业务逻辑”来中断,是安全且合理的做法。不要想着用“异常、崩溃”方法去结束什么任务。你动用你的业务数据结构来获得中止信号,这才是合理的。
  • 打赏
  • 举报
回复
异步处理绝不能使用阻塞的 Wait,这等于是人返祖成猴子了。

异步处理要合理中断,那么应该用“业务逻辑”来中断。例如
using System;
using System.Threading.Tasks;

namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
bool flag = false;
var f = new Func<bool>(() => flag);
test1(f);
loop:
{
Console.WriteLine("..................按1中断测试过程,按2结束程序");
var a = Console.ReadKey();
switch (a.KeyChar)
{
case '1':
flag = true;
goto loop;
case '2':
break;
default:
goto loop;
}

}
}

static async void test1(Func<bool> 是否中断)
{
await Task.Yield();
while (!是否中断())
{
Console.Write(".");
await Task.Delay(1000);
}
}
}
}
wanghui0380 2020-06-08
  • 打赏
  • 举报
回复
CancelToken
stevenjin 2020-06-08
  • 打赏
  • 举报
回复
补充一下,在任何要终止的地方,这个写就行了: cancelTokenSource.Cancel();
stevenjin 2020-06-08
  • 打赏
  • 举报
回复
嗯,这个非常 管用,解决了我现在的问题。CancelToken相当于一标志了。 我大概是这样用的: 1.声明一个task static CancellationTokenSource cancelTokenSource = new CancellationTokenSource(); 2.在代码运行的地方,这样写: Task.Run(() => { lock (lockUpdate) { UpdateValues(); } }, cancelTokenSource.Token); 3.每次执行时判断,如果标志为已取消,就不执行 UpdateValues(){ if (cancelTokenSource.IsCancellationRequested) { return; }
dmankill 2020-06-08
  • 打赏
  • 举报
回复
https://www.cnblogs.com/luohengstudy/p/5623451.html CancellationTokenSource 用这个

110,537

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧