取消任务是抛出异常 [英] Cancelling a Task is throwing an exception

查看:212
本文介绍了取消任务是抛出异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从我读过有关的任务,下面的code应该取消当前正在执行的任务,而不抛出异常。我是IM pression下的任务取消的整点是要礼貌地问的任务停止不中断线程。

从以下程序的输出是:


  

倾销例外


  
  

[OperationCanceledException]


  
  

消和最后计算的黄金回来了。


我想取消,以避免任何异常。我怎样才能做到这一点?

 无效的主要()
{
    VAR的CancellationToken =新CancellationTokenSource();    VAR任务=新任务< INT>(()=> {
        返回CalculatePrime(cancellationToken.Token,10000);
    },cancellationToken.Token);    尝试
    {
        task.Start();
        Thread.sleep代码(100);
        cancellationToken.Cancel();
        task.Wait(cancellationToken.Token);
    }
    赶上(例外五)
    {
        Console.WriteLine(倾销除外);
        e.Dump();
    }
}INT CalculatePrime(的CancellationToken cancelToken,目标位)
{
    INT因素;
    INT lastPrime = 0;    INT C =(int)的数字;    对于(INT NUM = 2; NUM c为C; NUM ++)
    {
        布尔isprime = TRUE;
        因数= 0;        如果(cancelToken.IsCancellationRequested)
        {
            Console.WriteLine(消和最后计算的黄金回来了。);
            //cancelToken.ThrowIfCancellationRequested();
            返回lastPrime;
        }        //看看num是整除
        的for(int i = 2; I< = NUM​​ / 2;我++)
        {
            如果((NUM%I)== 0)
            {
                // num是整除 - 不是素数
                isprime = FALSE;
                系数= I;
            }
        }        如果(isprime)
        {
            lastPrime = NUM​​;
        }
    }    返回lastPrime;
}


解决方案

您是在这条线明确地抛出一个异常:

  cancelToken.ThrowIfCancellationRequested();

如果你想优雅地退出了任务,那么你只需要摆脱线的。

通常人们用这个作为控制机制,以确保当前的处理没有得到潜在运行任何额外的code中止。此外,没有必要打电话时检查取消 ThrowIfCancellationRequested(),因为它在功能上等同于:

 如果(token.IsCancellationRequested)
    抛出新OperationCanceledException(令牌);

在使用 ThrowIfCancellationRequested()你的任务可能看起来更像是这样的:

  INT CalculatePrime(的CancellationToken cancelToken,目标位){
    尝试{
        而(真){
            cancelToken.ThrowIfCancellationRequested();            //长工作这里...
        }
    }
    最后{
        //做一些清理
    }
}

此外, Task.Wait(的CancellationToken)将如果令牌被取消抛出异常。要使用这个方法,你需要换你等待的呼叫在<$​​ C $ C>的try ... catch 块。

MSDN:如何取消任务

From what I've read about Tasks, the following code should cancel the currently executing task without throwing an exception. I was under the impression that the whole point of task cancellation was to politely "ask" the task to stop without aborting threads.

The output from the following program is:

Dumping exception

[OperationCanceledException]

Cancelling and returning last calculated prime.

I am trying to avoid any exceptions when cancelling. How can I accomplish this?

void Main()
{
    var cancellationToken = new CancellationTokenSource();

    var task = new Task<int>(() => {
        return CalculatePrime(cancellationToken.Token, 10000);
    }, cancellationToken.Token);

    try
    {
        task.Start();
        Thread.Sleep(100);
        cancellationToken.Cancel();
        task.Wait(cancellationToken.Token);         
    }
    catch (Exception e)
    {
        Console.WriteLine("Dumping exception");
        e.Dump();
    }
}

int CalculatePrime(CancellationToken cancelToken, object digits)
{  
    int factor; 
    int lastPrime = 0;

    int c = (int)digits;

    for (int num = 2; num < c; num++)
    { 
        bool isprime = true;
        factor = 0; 

        if (cancelToken.IsCancellationRequested)
        {
            Console.WriteLine ("Cancelling and returning last calculated prime.");
            //cancelToken.ThrowIfCancellationRequested();
            return lastPrime;
        }

        // see if num is evenly divisible 
        for (int i = 2; i <= num/2; i++)
        { 
            if ((num % i) == 0)
            {             
                // num is evenly divisible -- not prime 
                isprime = false; 
                factor = i; 
            }
        } 

        if (isprime)
        {
            lastPrime = num;
        }
    }

    return lastPrime;
}

解决方案

You are explicitly throwing an Exception on this line:

cancelToken.ThrowIfCancellationRequested();

If you want to gracefully exit the task, then you simply need to get rid of that line.

Typically people use this as a control mechanism to ensure the current processing gets aborted without potentially running any extra code. Also, there is no need to check for cancellation when calling ThrowIfCancellationRequested() since it is functionally equivalent to:

if (token.IsCancellationRequested) 
    throw new OperationCanceledException(token);

When using ThrowIfCancellationRequested() your Task might look more like this:

int CalculatePrime(CancellationToken cancelToken, object digits) {
    try{
        while(true){
            cancelToken.ThrowIfCancellationRequested();

            //Long operation here...
        }
    }
    finally{
        //Do some cleanup
    }
}

Also, Task.Wait(CancellationToken) will throw an exception if the token was cancelled. To use this method, you will need to wrap your Wait call in a Try...Catch block.

MSDN: How to Cancel a Task

这篇关于取消任务是抛出异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆