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

C# 并行运行两个任务,如果第一个任务完成.NET,则取消第二个任务,c#,.net,multithreading,asynchronous,task,C#,.net,Multithreading,Asynchronous,Task,如果有两个方法我想在不同的线程上并行运行,让我们称它们为Task1和Task2。如果Task2在Task1之前完成,则我希望将两者的结果合并到一个列表中。如果Task1完成且Task2仍在运行,则应取消Task2以避免进一步处理。Wheall不工作,因为它将等待两个任务。当任何一个都不工作时,因为如果其中一个先完成,它将返回。这就是我提出的解决方案 static void Main(string[] args) { var tokenSource = new CancellationTo

如果有两个方法我想在不同的线程上并行运行,让我们称它们为Task1和Task2。如果Task2在Task1之前完成,则我希望将两者的结果合并到一个列表中。如果Task1完成且Task2仍在运行,则应取消Task2以避免进一步处理。Wheall不工作,因为它将等待两个任务。当任何一个都不工作时,因为如果其中一个先完成,它将返回。

这就是我提出的解决方案

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;
}
static void Main(字符串[]args)
{
var tokenSource=new CancellationTokenSource();
var token=tokenSource.token;
var比率=新列表();
尝试
{
var p44Task=Task.Factory.StartNew(()=>GetP44Rates(token),token);
var-mgRates=await-GetMGRates();
费率。添加范围(管理费率);
if(p44Task.IsCompleted&&p44Task.Result.IsCompleted)
{
rates.AddRange(p44Task.Result.Result);
}
其他的
{
//取消p44任务
tokenSource.Cancel();
}
}
捕获(例外e)
{
tokenSource.Cancel();
控制台写入线(e);
}
foreach(利率中的var率)
{
控制台写入线(速率);
}
Console.ReadLine();
}
专用静态异步任务GetMGRates(CancellationToken CancellationToken)
{
var比率=新列表();
对于(变量i=0;i<10;i++)
{
加上($“MG:{i}”);
Console.WriteLine($“MG in{i}”);
等待任务。延迟(1000);
}
回报率;
}
私有静态异步任务GetP44Rates(CancellationToken ct)
{
var比率=新列表();
对于(变量i=0;i<50;i++)
{
加上($“P44:{i}”);
Console.WriteLine($“P44:{i}”);
等待任务。延迟(1000);
如果(ct.IsCancellationRequested)
{
Console.WriteLine(“再见,第44页”);
Console.WriteLine(“\n按Enter键退出”);
ct.ThrowIfCancellationRequested();
}
}
回报率;
}

创建一个CancellationTokenSource并将其Token属性传递给Task2,Task2需要通过在某些点调用Token的ThrowIfCancellationRequested方法来检查是否请求取消。在Task1结束时,调用CancellationTokenSource的Cancel方法以请求取消Task2。Use WhenAll–当Task2被取消并且您等待WhenAll结果任务时,它会抛出一个OperationCancelledException,这是预期行为,因此您只需要捕获它。我认为这是一个问题,因为我最初确实有代码。然后我把代码贴出来作为答案,因为没有人回答这个问题。然后国防部让我把我的代码放在问题里。“我不能用这个网站取胜。@BradFiresheets不是版主,它只是一个普通用户。主要的问题是,你发布了一个答案,但没有说你在回答这个问题,而是表明这是一个更新的,但仍然不完整的解决方案。这应该是对问题的修改。如果你有一个答案,并且不再有问题,那么它应该作为答案发布。是的,这是我自己问题的答案。我想你看不到删除的答案(我可以,它是红色的)