Как остановить выполнение асинхронного метода в C#?

Я использую асинхронный метод. Как я могу остановить его выполнение, когда Timer вызывает событие timeout?

Мой код:

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();
}

2 ответа

Вот как работает отмена задачи:

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;
}

Вы должны ответить на изменение в собственности ct.IsCancellationRequested знать, когда отменить задачу. Для одного потока / задачи не существует безопасного способа отменить другой поток / задачу.

В вашем случае кажется, что вы пытаетесь вызвать единственный метод, который не знает о CancellationToken поэтому вы не можете отменить эту задачу безопасно. Вы должны позволить потоку / задаче продолжать выполнение.

Я думаю, что вы можете попробовать упомянуть, когда отменить его. Что-то вроде

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

Также вам нужно использовать токен отмены в вызываемых методах. Вот когда вы будете знать, когда отменить.

Другие вопросы по тегам