Pergunta

I'm starting a few tests about asynchronous programing in .net and now i'm stuck at trying ti cancel a long operation using cancellationToken.

So I have the following code:

CancellationTokenSource cancelationToken = new CancellationTokenSource();

My buttons to start the operations

    private void button2_Click(object sender, EventArgs e)
    {
        cancelationToken.Cancel(true);
    }

    private void button1_Click(object sender, EventArgs e)
    {
        StartOperation(cancelationToken.Token);
    }

And finally my operations

    private async void StartOperation(CancellationToken cancelToken)
    {
        await GetItensFromDatabase2(cancelToken);
    }

    public static Task<int> GetItensFromDatabase(CancellationToken cancelToken)
    {
        //cancelToken.Register( () => Console.WriteLine("Canceled") );
        return Task.Factory.StartNew<int>(() =>
        {
            int result = 0;

            cancelToken.ThrowIfCancellationRequested();

            result = MyLongOperation();  // Simulates my operation -> I want to cancel while this operation is still running

            return result;

        }, cancelToken);
    }

So, how to cancel MyLongOperation() method ? Is it possible to do ?

Foi útil?

Solução

It is not possible to cancel in any point, the purpose of CancellationToken is to allow user to cancel the operation, when the long running operation expect that...

while(!finished)
{
     cancelToken.ThrowIfCancellationRequested();
     //Some not cancelable operations
}

Here is more common method of cancelable method

private static void LongRunning(CancellationToken cancelToken)
{
    while (true)
    {
        if(cancelToken.IsCancellationRequested)
        {
            return;
        }
        //Not canceled, continue to work
    }
}

The idea is, that user requests cancellation, but only executor decides when to stop his work. Usually executor do cancellation after reaching some "safe-point"

It is not good experiance to Abort long running operations without asking oppinion, a lot of posts have been written about this.

Outras dicas

Well for starters you would have an issue that if you have already run through the logic which says "cancelToken.ThrowIfCancellationRequested" and then you cancel. How will the "MyLongOperation" know that you have cancelled the task? :)

Cancelling a long running task usually takes in a CancellationToken as an argument so the code would look something like:

// Check if cancelled
// do work part 1
// Check if cancelled
// do work part 2

The granularity of the cancellable operations is upto the developer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top