C# 当Task.IsCancelled设置为true时?

C# 当Task.IsCancelled设置为true时?,c#,task-parallel-library,task,cancellationtokensource,cancellation-token,C#,Task Parallel Library,Task,Cancellationtokensource,Cancellation Token,何时将来Task.IsCanceled=true 代码: var cts=new CancellationTokenSource(); 字符串结果=”; cts.1(10000); 尝试 { Task t=Task.Run(()=> { 使用(var stream=new WebClient().OpenRead(“http://www.rediffmail.com")) { result=“success!”; } cts.Token.ThrowIfCancellationRequested(

何时将来Task.IsCanceled=true

代码:

var cts=new CancellationTokenSource();
字符串结果=”;
cts.1(10000);
尝试
{
Task t=Task.Run(()=>
{
使用(var stream=new WebClient().OpenRead(“http://www.rediffmail.com"))
{
result=“success!”;
}
cts.Token.ThrowIfCancellationRequested();
},cts.Token);
秒表计时器=新秒表();
timer.Start();
while(计时器正在运行)
{
如果(timer.elapsedmillesons来自文档:

任务将在TaskStatus.Cancelled状态下完成,条件如下:

  • 在任务开始执行之前,其CancellationToken已标记为取消

  • 任务通过抛出带有相同CancellationToken的OperationCanceledException来确认其已发出信号的CancellationToken上的取消请求

  • 任务通过调用CancellationToken上的ThrowIfCancellationRequested方法,在其已发出信号的CancellationToken上确认取消请求

  • 因此,基本上,您需要在任务中抛出一个
    OperationCanceledException
    ,以强制执行状态,例如,在取消之后执行
    cts.Token.ThrowIfCancellationRequested()


    但是这个机制的意图有点相反。你可以在用户按下表单上的“取消”按钮时(从任务之外)取消源代码任务只是验证是否在某些安全模式下请求取消以取消其代码点。

    您必须将令牌传递给您的方法。它应该检查令牌并尊重对
    取消令牌源的
    取消()
    的调用

    或者你自己做:

    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);
        }
    }
    
    输出是抛出一个
    操作CanceledException
    ,结果为

    真的

    如果删除
    ct.ThrowIfCancellationRequested();
    部分,它将显示

    假的

    编辑:

    现在,您已经更新了问题和对此的一些评论。首先,您将不再需要计时器,因为您正在使用
    CancelAfter
    方法。其次,您需要
    等待您的任务。这样做:

    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
    ,但当然只有当调用
    WebClient
    的时间超过10秒时才是如此。

    请包含一个。您显示的内容不完整。取消令牌还不够,您需要检查
    方法
    取消作业的代码您可以显示代码吗在等待任务t之前?为了正确起见,如果方法运行时间超过20秒,您希望取消整个操作,是吗?我将在哪里共享代码。此处无法共享代码。显示太长任务t=Task.Factory.StartNew(()=>{myResult=method();//并行请求处理},cts.Token);//一段时间后cts.cancel cts.Token.throwifccancellationrequested();是否可能?此处t.iscancelled永远不会为true。您能显示等待任务t的代码吗?为了正确起见,如果方法运行时间超过20秒,您希望取消整个操作,是吗?如何共享代码?此处出现了太长的字符。请将其编辑或添加到您的问题中,这是最好的方法y、 它不工作。Web客户端需要10秒。但它仍然没有用于捕获操作。在获得结果后,由于等待操作,只会返回结果。如果不等待,可能吗?
    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); 
    }