Nested task inside loop

拜拜、爱过 提交于 2019-12-06 13:17:02

问题


I'm trying to implement a nested task inside a loop - this is the pattern I have so far, however I'm far from sure as this is the first time I've used the parallel task library.

The parent (tier) task should wait for the children (node) tasks to complete.

    public int NestedTask(IEnumerable<MatchTier> tierNodes)
    {
        var tier = Task<int>.Factory.StartNew(() =>
        {
            Task<int> node = null;

            foreach(var n in tierNodes)
            {
                node = Task<int>.Factory.StartNew(() =>
                {
                    // Task logic goes here

                    return 1; // temp placeholder
                });

                // if a valid value is returned then exit this loop
            }

            return node.Result;

        });

        return tier.Result;
    }

The child nodes loop until the first valid value is returned, then the loop should be exited, passing the valid value to the parent.

Both the child and parent nodes require a timeout too. Each child will be allowed approx 3 seconds to run after which the process will be timed out and the next node interrogated.

the parent has an overall timeout value of approx 15 - 20 seconds, after which, if no valid response has been recieved, it too should terminate.

Does this seem logical?


回答1:


As stated task.Wait(), task.Result (wait and grab result) and Task.WaitAll(theTaskCollection) are the ways to do this. I've changed your implementation slightly to account for that but I'm very unsure of what you really want to return. The outer task I removed since it didn't seem to be needed.

public int NestedTask(IEnumerable<MatchTier> tierNodes)
{
  var tasks = tierNodes.Select(node => Task<int>.Factory.StartNew(() =>
            {
                // Task logic goes here
                return 1; // temp placeholder
            })).ToList(); // Enumerate to start tasks, not doing this would case WaitAll to start them one at a time (i believe)

  if (!Task.WaitAll(tasks, timeOutInMilliseconds))
    // Handle timeout...

  return tasks.First().Result; // Is this what you want?
}

EDIT: Adding modified solution.

public int NestedTask(IEnumerable<string> tierNodes)
{
  int parentTimeout = 15 * 1000;
  int childTimeout = 3 * 1000;

  var tier = Task<int>.Factory.StartNew(() =>
  {
      foreach (var n in tierNodes)
      {
          var node = Task<int>.Factory.StartNew(() =>
          {
              // Task logic goes here
              return 1;
          });

          // If we get the result we return it, else we wait
          if (node.Wait(childTimeout))
              return node.Result;
      }
      throw new Exception("did not get result!");
  });

  if (!tier.Wait(parentTimeout))
  {
      // The child will continue on running though.
      throw new TimeoutException("parent timed out");
  }
  else if (tier.Exception != null)
  {
      // We have an error
      throw tier.Exception.InnerException;
  }

  return tier.Result;
}



回答2:


to wait for a task to complete do

node.Wait();

to wait for task up until some ticks do

node.Wait(timeToWait);

or to wait for them all to complete

Task.WaitAll(tasks);

and you should read here for more information



来源:https://stackoverflow.com/questions/18460464/nested-task-inside-loop

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!