Task.WaitAll с CancelationToken - PullRequest
       7

Task.WaitAll с CancelationToken

0 голосов
/ 02 сентября 2018

Мне нужно выполнить много методов одновременно и в результате всех объединить их в один список. В следующем примере я жду 3 секунды для каждого метода, но в одном из них я добавил сон (10 секунд), чтобы проверить результат, а он не является ожидаемым. Метод никогда не отменяет и ждет эти 10 секунд. В чем проблема? Спасибо!

var result = await Task.Run(() => Load<MyCustomClass>(OneMethod(), OtherMethod()));

private List<T> OneMethod()
{
    return new List<T>();
}

private List<T> OtherMethod()
{
    Thread.Sleep(10000);

    return new List<T>();
}

private async Task<List<T>> Load<T>(params List<T>[] taskList)
{
    try
    {
        return (await Task.WhenAll(taskList.Select(x =>
            Task.Run(() => x, new CancellationTokenSource(3000).Token)))).SelectMany(x => x).ToList();
    }
    catch (Exception currentException)
    {
        //BLA BLA BLA
    }

    return new List<T>();
}

1 Ответ

0 голосов
/ 02 сентября 2018

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

var t = new CancellationTokenSource(3000).Token
var result = await Task.Run(() => Load<MyCustomClass>(OneMethod(t), OtherMethod(t)));

private List<T> OneMethod(CancellationToken t)
{
    token.ThrowIfCancellationRequested();
    return new List<T>();
}

private List<T> OtherMethod(CancellationToken t)
{
    Thread.Sleep(10000);
    token.ThrowIfCancellationRequested();
    // or you can check if cancellation is requested
    // if (token.IsCancellationRequested) ...
    return new List<T>();
}

private async Task<List<T>> Load<T>(params List<T>[] taskList)
{
    try
    {
        return (await Task.WhenAll(taskList.Select(x =>
            Task.Run(() => x)))).SelectMany(x => x).ToList();
    }
    catch (Exception currentException)
    {
        //BLA BLA BLA
    }

    return new List<T>();
}

См. этот вопрос

...