并行运行2个任务,如果第一个任务完成.NET,则取消第二个任务

时间:2017-07-28 19:12:10

标签: c# .net multithreading asynchronous task

如果我想在不同的线程上并行运行2个方法,那么我们称它们为Task1和Task2。如果Task2在Task1之前完成,那么我希望将两者的结果合并到一个列表中。如果Task1完成且Task2仍在运行,它应取消Task2以避免进一步处理。 WhenAll不起作用,因为它将等待两个任务。 WhenAny不起作用,因为如果先完成,它将返回。

1 个答案:

答案 0 :(得分:0)

这是我提出的解决方案。

static void Main(string[] args)
{
    var tokenSource = new CancellationTokenSource();
    var token = tokenSource.Token;
    var rates = new List<string>();

    try
    {
        var p44Task = Task.Factory.StartNew(() => GetP44Rates(token), token);

        var mgRates = await GetMGRates();

        rates.AddRange(mgRates);

        if (p44Task.IsCompleted && p44Task.Result.IsCompleted)
        {
            rates.AddRange(p44Task.Result.Result);
        }
        else
        {
            // Cancel the p44 task
            tokenSource.Cancel();
        }
    }
    catch (Exception e)
    {
        tokenSource.Cancel();
        Console.WriteLine(e);
    }

    foreach (var rate in rates)
    {
        Console.WriteLine(rate);
    }

    Console.ReadLine();

}

private static async Task<List<string>> GetMGRates(CancellationToken cancellationToken)
{
    var rates = new List<string>();

    for (var i = 0; i < 10; i++)
    {
        rates.Add($"MG: {i}");
        Console.WriteLine($"MG inside {i}");
        await Task.Delay(1000);
    }


    return rates;
}

private static async Task<List<string>> GetP44Rates(CancellationToken ct)
{
    var rates = new List<string>();

    for (var i = 0; i < 50; i++)
    {
        rates.Add($"P44: {i}");
        Console.WriteLine($"P44: {i}");
        await Task.Delay(1000);

        if (ct.IsCancellationRequested)
        {
            Console.WriteLine("bye from p44.");
            Console.WriteLine("\nPress Enter to quit.");

            ct.ThrowIfCancellationRequested();
        }
    }

    return rates;
}