Task.WaitAll与CancellationToken

时间:2018-09-02 03:41:08

标签: c# wpf asynchronous async-await

我需要同时执行许多方法和所有方法的结果,并将它们串联在一个列表中。在下面的示例中,我为每种方法等待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 :(得分:2)

您必须将CancellationToken传递给方法,并检查是否请求了cancelToken或直接引发异常。

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

请参见this question