如何在现有任务<tresult>

时间:2015-12-23 05:40:16

标签: c# task

我正试图在.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”可以是任何可以传递的东西,而不仅限于一个字符串。

1 个答案:

答案 0 :(得分:0)

为什么您需要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方法)。