什么时候会来 Task.IsCanceled = true;
代码:
var cts = new CancellationTokenSource();
string result = "";
cts.CancelAfter(10000);
try
{
Task t = Task.Run(() =>
{
using (var stream = new WebClient().OpenRead("http://www.rediffmail.com"))
{
result = "success!";
}
cts.Token.ThrowIfCancellationRequested();
}, cts.Token);
Stopwatch timer = new Stopwatch();
timer.Start();
while (timer.IsRunning)
{
if (timer.ElapsedMilliseconds <= 10000)
{
if (result != ""){
timer.Stop();
Console.WriteLine(result);
}
}
else
{
timer.Stop();
//cts.Cancel();
//cts.Token.ThrowIfCancellationRequested();
}
}
}
catch (OperationCanceledException)
{
Console.WriteLine(t.IsCanceled); // still its appear in false.
}
我的要求是 - 任务未完成最多10秒,需要取消任务。
所以我正在设置计时器并注意到给定的秒数。未完成的意思是取消任务并显示错误信息。
答案 0 :(得分:3)
您必须将令牌传递给您的方法。它应该检查令牌并尊重对Cancel()
的{{1}}的呼叫。
或者你自己做:
CancellationTokenSource
一个完整的例子就是:
Task t = Task.Factory.StartNew(() =>
{
myResult = method(); // Request processing in parallel
cts.Token.ThrowIfCancellationRequested(); // React on cancellation
}, cts.Token);
输出是抛出async Task Main()
{
var cts = new CancellationTokenSource();
var ct = cts.Token;
cts.CancelAfter(500);
Task t = null;
try
{
t = Task.Run(() => { Thread.Sleep(1000); ct.ThrowIfCancellationRequested(); }, ct);
await t;
Console.WriteLine(t.IsCanceled);
}
catch (OperationCanceledException)
{
Console.WriteLine(t.IsCanceled);
}
}
,结果是
真
如果您删除了OperationCanceledException
部分,则会显示
假
修改强>
现在,您已经更新了问题,对此提出了一些意见。首先,由于您使用ct.ThrowIfCancellationRequested();
方法,因此您不再需要计时器。其次,您需要CancelAfter
您的任务。所以这就是这样的:
await
这应该表明string result = "";
cts.CancelAfter(10000);
Task t = null;
try
{
t = Task.Run(() =>
{
using (var stream = new WebClient().OpenRead("http://www.rediffmail.com"))
{
cts.Token.ThrowIfCancellationRequested();
result = "success!";
}
}, cts.Token);
await t;
}
catch (OperationCanceledException)
{
Console.WriteLine(t.IsCanceled);
}
是t.IsCanceled
,但当然只有当true
的调用时间超过10秒时才会显示。
答案 1 :(得分:1)
来自文档:
在以下任何条件下,任务将在TaskStatus.Canceled状态下完成:
在任务开始执行之前,它的CancellationToken被标记为取消。
该任务通过抛出一个具有相同CancellationToken的OperationCanceledException来确认已经发出信号的CancellationToken的取消请求。
- 醇>
该任务通过在CancellationToken上调用ThrowIfCancellationRequested方法来确认已经发出信号的CancellationToken的取消请求。
所以基本上你需要在你的任务中抛出一个OperationCanceledException
来强制状态,例如在你取消它之后执行cts.Token.ThrowIfCancellationRequested()
。
但是这种机制的意图有点相反。当用户按下表单上的取消按钮(从任务外部)时,您取消源说,任务只是验证是否在某些保存中取消了取消以取消其代码点。