如何在现有任务上使用带有条件的ContinueWith<;TResult>;

本文关键字:ContinueWith 有条件 lt gt TResult 任务 | 更新日期: 2023-09-27 18:27:52

我正试图获得有关.ContinueWith()方法的一些帮助。我知道一些类似Task<Task<bool>> t2 = nextTask.ContinueWith(t => T.FirstLevel("GG")); 的东西

正如你在下面看到的,这是我试图做的一个演示。我的第一级任务返回一个bool,它将决定继续执行哪个任务,我的第二级任务也将返回一个bool,以决定是返回执行第一级还是退出。这就是我被卡住的地方,不过我不想让它递归。

有人能帮忙吗?

我知道可以使用事件处理程序来解决这个问题,但目前实际的应用程序代码更改起来非常复杂。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Continuewith
{
   class Program
   {
     static void Main(string[] args)
     {
        tester();
        Console.ReadKey();
     }
    static async void tester()
    {
        TaskFunctions T = new TaskFunctions();
        List<string> p = new List<string>() { "111"};
        List<Task<bool>> CocurrentTasks = new List<Task<bool>>();
        foreach (string s in p)
        {
            CocurrentTasks.Add(T.FirstLevel(s));
        }
        while (CocurrentTasks.Count > 0)
        {
            Task<bool> nextTask = await Task.WhenAny(CocurrentTasks);
            if(await nextTask)
            {
               //do second level
            }
            else
            {
               //do first level
            }
            CocurrentTasks.Remove(nextTask);
        }
    }
}
class TaskFunctions
{
    public async Task<bool> FirstLevel(string gg)
    {
        Console.WriteLine(gg);
        Random random = new Random();
        int randomNumber = random.Next(0, 10);
        await Task.Delay(500 * randomNumber); //other real useful Task Function will be in place to take up the time
        if (randomNumber > 5)
            return true;
        else
            return false;         
    }
    public async Task<bool> SecondLevel(string jj)
    {
        Console.WriteLine(jj);
        Random random = new Random();
        int randomNumber = random.Next(0, 10);
        await Task.Delay(500 * randomNumber); //other real useful Task Function will be in place to take up the time
        if (randomNumber > 5)
            return true;
        else
            return false;
    }
}
}

这是我的解决方案,不完美,但我可以使用它。

static async void tester()
    {
        TaskFunctions T = new TaskFunctions();
        List<string> p = new List<string>() { "111"};
        List<Task<bool>> CocurrentTasks = new List<Task<bool>>();
        foreach (string s in p)
        {
            CocurrentTasks.Add(T.FirstLevel(s));
        }
        while (CocurrentTasks.Count > 0)
        {
            Task<bool> nextTask = await Task.WhenAny(CocurrentTasks);
            if(await nextTask)
            {
               Task<Task<bool>> t2 = nextTask.ContinueWith(t => T.SecondLevel("GG"));
               if(!await t2.Unwarp())
               {
                  CocurrentTasks.Add(T.FirstLevel("111"));
               }
            }
            else
            {
               CocurrentTasks.Add(T.FirstLevel("111"));
            }
            CocurrentTasks.Remove(nextTask);
        }
    }

然而,这需要第一级任务返回"111",以便程序将再次执行该特定数据。"111"可以是任何可以传递的信息,而不仅仅限于字符串。

如何在现有任务上使用带有条件的ContinueWith<;TResult>;

为什么需要FirstLevelSecondLevel是单独的Task?也许作为一个连续Task的一部分来控制这些调用会更容易?基本上,您希望将while中的代码移动到一种方法:

static async void tester()
{
    TaskFunctions T = new TaskFunctions();
    List<string> p = new List<string>() { "111" };
    List<Task> CocurrentTasks = new List<Task>();
    foreach (string s in p)
    {
        CocurrentTasks.Add(CallConcurrentTasks(T, s));
    }
    while (CocurrentTasks.Count > 0)
    {
        var nextTask = await Task.WhenAny(CocurrentTasks);            
        CocurrentTasks.Remove(nextTask);
    }
}
static async Task CallConcurrentTasks(TaskFunctions t, string arg)
{
    do
    {
        if (await t.FirstLevel(arg))
        {
            if (!await T.SecondLevel("GG"))
            {
                return;
            }
        }
    }
    while (true);   //you should probably make some additional end condition here?
}

我希望我做得对。或者,您可以为ConcurrentTasks集合使用线程安全列表,并在不做任何更改的情况下使用while代码(集合作为参数传递给CallConcurrentTasks方法)。