How to create an asynchronous method that is cancelable?

3

How to create an asynchronous method that is cancelable?

In this context, the DoFoo() method does things that can not be simply stopped, such as reading and writing files, and by canceling, I have to wait for these I / O operations to complete for the method to be canceled. / p>

private async void Button_Click()
{
    await DoFoo();
}

private async void Cancelar_Click()
{
    // cancelamento do método DoFoo()
    // ...
}

private async Task DoFoo()
{
    // operações de I/O
    File.WriteAllText("path", "conteudo");

    // operações de longa execução

    // ...
}
    
asked by anonymous 28.07.2017 / 15:41

1 answer

3

You need to create a cancellation token in the method. You can only cancel what is prepared for cancellation. In general, the asynchronous .NET API supports.

CancellationTokenSource cts;

private async void Button_Click() {
    cts = new CancellationTokenSource();
    try {
        await DoFoo(cts.Token);
    } catch (OperationCanceledException ex) {
        //trata o cancelamento
    }
}

private async void Cancelar_Click() => cts.Cancel();

private async Task DoFoo(CancellationToken ct) {
    // operações de I/O
    File.WriteAllText("path", "conteudo");
    for (var item in lista) {
        //faz o que quiser aqui
        ct.ThrowIfCancellationRequested(); //isto pode ser muito lento
    }
}

I placed GitHub for future reference .

It is common not to check for a cancellation request at each loop step since verification has a reasonable cost, so it can filter when accepting a cancellation request, perhaps every 1000 items processed, for example.

Certainly you have other ways to do it depending on the purpose. Exception need not be the mechanism of treatment.

Documentation for CancellationTokenSource .

CancellationToken documentation .

    
28.07.2017 / 16:19