简体   繁体   中英

how to stop async method execution in c#?

I am using an asynchronous method. How can I stop its execution when a Timer raises a timeout event?

My code:

public async Task<object> Method()
{
    cts = new CancellationTokenSource();
    try
    {
        timer = new System.Timers.Timer(3000);
        timer.Start();
        timer.Elapsed += (sender, e) =>
        {
            try
            {
                timer_Elapsed(sender, e, cts.Token, thread);
            }
            catch (OperationCanceledException)
            {
                return;
            }
            catch (Exception ex)
            {
                return;
            }
        };
        await methodAsync(cts.Token);
        return "message";
    }
    catch (OperationCanceledException)
    {
        return "cancelled";
    }
    catch (Exception ex)
    {
        return ex.Message;
    }
}

// Async Call
public async Task<object> methodAsync(CancellationToken ct)
{
    try
    {
        pdfDocument = htmlConverter.Convert("path", "");
    }
    catch(Exception ex)
    {
        return x.Message;
    }
}

// Timer event
void timer_Elapsed(object sender, ElapsedEventArgs e, CancellationToken ct)
{ 
    cts.Cancel();
    ct.ThrowIfCancellationRequested();
}

Here's how canceling a task works:

public async Task<object> Method()
{
    cts = new CancellationTokenSource();
    await methodAsync(cts.Token);
    return "message";
}

public Task<object> methodAsync(CancellationToken ct)
{
    for (var i = 0; i < 1000000; i++)
    {
        if (ct.IsCancellationRequested)
        {
            break;
        }
        //Do a small part of the overall task based on `i`
    }
    return result;
}

You have to respond to the change in the property of ct.IsCancellationRequested to know when to cancel the task. There is no safe way for one thread/task to cancel another thread/task.

In your case it appears that you are trying to call a single method that doesn't know about the CancellationToken so you can not cancel this task safely. You must let the thread/task continue to completion.

I think you can try mentioning when to cancel it. Something like

cts.CancelAfter(TimeSpan.FromMilliseconds(5000));

Also, you need to use the cancellation token in the called methods. That's when you will know when to cancel.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM