如何创建并行任务来调用相同的方法 [英] How create a parallel task to call the same method

查看:62
本文介绍了如何创建并行任务来调用相同的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个方法可以验证一个条件是否有效。但是这个验证有点重。因此,我需要使用并行接收来验证这一点,当任何此验证停止然后我取消所有其他任务时。因此,我需要使用并行任务验证这一点,当某些验证首先完成后,我将取消所有其他任务。返回结果。

为了更清楚,我将只使用一种方法执行此验证,但传递不同的值。首先回复我的电话我将取消其他任务平行任务。



我尝试了什么:



我用简单的线程试过这个操作,但是效果不好。

I have a method that verifies if one condition is valid. But this verification is a little heavy. So, I need to verify this with parallel taks, when anyone this verification stop then I cancel all the others tasks. So, I need to verify this with parallel tasks, when some those verification has finished first then I'll cancel all the others tasks. And returne the results.
To be more clear, I'll execute this verification with only one method but passing different values. The call which return me first I'll cancel the others parallels tasks.

What I have tried:

I have tried this operation with simple thread, but it doesn't work well.

推荐答案

看看 Parallel.ForEach Method

Take a look at Parallel.ForEach Method:
Parallel.ForEach(myTasks, t => t.DoSomethingInBackground());

Console.Write("All tasks Completed. Now we can do further processing");


当我第一次看到这个问题时,我想到了 Reactive Extensions(Rx) [ ^ ]

花了一段时间才有机会解决这个问题,但这里有一个例子,其中每个(代理一个)服务器/域的查询在单独的任务中并行完成,Rx用于等待返回true的第一个。一旦成功发生,那么 CancellationToken 用于通知任何尚未完成的查询,它可以退出。 (我假设您的验证方法可以使用 CancellationToken 在完成之前停止。)

When I first saw this question I thought of Reactive Extensions (Rx)[^]
It took a while to get a chance to work it up, but here is an example where each (proxy for a) query of the server/domain is done in parallel in a separate Task and Rx is used to wait for the first one that returns true. Once success happens, then the CancellationToken is used to notify any query that hasn't completed that it can quit. (I'm assuming that your verification method can use a CancellationToken to stop before completing.)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication7
{
  class Program
  {
    static  void Main(string[] args)
    {
      RunIt();
      Console.ReadLine();
    }

    // This is so the individual queries can return both the status and 
    // something that identifies the input(s) that led to that succuss/fail
    private class Result
    {
      public readonly int Id;
      public bool Success { get; set; }
      public Result(int id)
      {
        Id = id;
        Success = false;
      }
    }
    static async void RunIt()
    {
      CancellationTokenSource cancellationSource = new CancellationTokenSource();
      CancellationToken token = cancellationSource.Token;
      // this List<int> values is the "proxy" for your set of server/domain
      // if in your case the servers & domains are independent vs. paired
      // then constructing the observableValues will be a bit trickier. :-)
      Random rand = new Random();
      List<int> values = Enumerable.Range(0, 10).Select(_ => rand.Next(1, 30)).ToList(); // ensure the values are "locked"
      Console.WriteLine("values=");
      foreach (var item in values)
      {
        Console.WriteLine(item);
      }
      Console.WriteLine();
      var observableValues = values.ToObservable();
      var tasks = observableValues.Select(x => Task.Run<Result>(() => {
        // This proxy for your validation "query" here just waits for the specified number of seconds, checking for cancellation each second
        // This is to simulate the queries each taking differing amounts of time
        Console.WriteLine("Start " + x.ToString());
        var res = new Result(x);
        for (int i = 0; i < x; i++)
        {
          if (token.IsCancellationRequested)
          {
            Console.WriteLine("Cancellation requested: {0}", x);
            return res;
          }
          Thread.Sleep(1000);
        }
        Console.WriteLine("Task = " + x.ToString());
        res.Success = (x & 1) != 0;   // Here the proxy for your validation success/failure is just that the input x is odd!
        return res;
      }, token));
      // by passing the token to the Task.Run() if cancellation happens before some Tasks get started, they just won't start at all

      // The Tasks don't actually start getting spun up until here:
      Result found = await tasks.Merge().FirstOrDefaultAsync(r => r.Success);
      cancellationSource.Cancel();
      Console.WriteLine(found == null ? "None found" : ("Found " + found.Id.ToString()));
    }
  }
}


这篇关于如何创建并行任务来调用相同的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆