Mri*_*boj 2 c# task task-parallel-library async-await
我测试的Linqpad创建了一个简单的控制台应用程序,思路是有工作的保证理解Task并创建工作,当逻辑Task被完成,故障或取消.我想只在Task完成但没有出错或取消时才执行逻辑.
void Main()
{
CancellationTokenSource cts = new CancellationTokenSource(new TimeSpan(0,0,0,0,1000));
Task t = Task.Run(() => Work(),cts.Token);
try
{
t.Wait();
}
catch
{
}
("Completed :: " + t.IsCompleted).Dump();
("Canceled :: " + t.IsCanceled).Dump();
("Faulted :: " + t.IsFaulted).Dump();
}
public async Task Work()
{
await Task.Delay(3000);
}
Run Code Online (Sandbox Code Playgroud)
以下是问题:
我能够自信地弄清楚已完成状态和故障状态,但即使在我看来这个代码应该导致任务取消,IsCanceled属性的值总是假的.
理想情况下,当Task出现故障时,即使我在try catch块中静默捕获异常,它也应显示IsCompleted为false,但它始终保持为true,目前Linqpad没有继续出错选项,但我假设,它如果我可以继续错误,将会变为假
我能够自信地找出Completed和Faulted状态,但即使在我看来这个代码应该导致Task取消,IsCanceled属性的值总是假的.
取消时没有自动化.要传递CancellationToken给Task.Run.如果在任务启动时取消,则取消将中断启动过程.任务运行后,任务的方法是检查取消令牌的责任.Wait不这样做.它甚至不知道取消令牌.因此,任务永远不会变成被取消的状态.
这是您观察取消的方式:
void Main()
{
CancellationTokenSource cts = new CancellationTokenSource(new TimeSpan(0,0,0,0,1000));
Task t = Task.Run(() => Work(cts.Token),cts.Token);
try
{
t.Wait();
}
catch
{
}
("Completed :: " + t.IsCompleted).Dump();
("Canceled :: " + t.IsCanceled).Dump();
("Faulted :: " + t.IsFaulted).Dump();
}
public async Task Work(CancellationToken token)
{
await Task.Delay(3000, token);
}
Run Code Online (Sandbox Code Playgroud)
理想情况下,当Task出现故障时,即使我在try catch块中静默捕获异常,它也应该将IsCompleted显示为false,但它始终保持为true
检查MSDN:
当任务处于以下三种最终状态之一时,IsCompleted将返回true:RanToCompletion,Faulted或Cancelled.
其他人已经注意到你的代码没有观察到CancellationToken,这就是为什么任务没有被取消.
我会回答这部分问题:
我想只在Task完成但没有出现故障或取消时才执行逻辑.
要做到这一点,请await在完成任务后输入逻辑:
await t;
// Your logic here.
Run Code Online (Sandbox Code Playgroud)
使用IsCanceled/ IsFaulted/ IsCompleted控制流是代码气味.
| 归档时间: |
|
| 查看次数: |
311 次 |
| 最近记录: |