Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 如果条件允许,请等待_.net_.net Core_Async Await_Parallel Processing_Parallel.foreach - Fatal编程技术网

.net 如果条件允许,请等待

.net 如果条件允许,请等待,.net,.net-core,async-await,parallel-processing,parallel.foreach,.net,.net Core,Async Await,Parallel Processing,Parallel.foreach,我正在使用并行Foreach。我还在foreach中调用webapi。我想控制来自api的响应。如果我得到了真值或某个值,我希望完成所有任务和每次迭代 我在stackoverflow中搜索,但看不到任何响应 Task<bool>[] tasks = new Task<bool>[customers.Count()]; CancellationTokenSource tokenSource = new CancellationTokenSource(); Cancellat

我正在使用并行Foreach。我还在foreach中调用webapi。我想控制来自api的响应。如果我得到了真值或某个值,我希望完成所有任务和每次迭代

我在stackoverflow中搜索,但看不到任何响应

Task<bool>[] tasks = new Task<bool>[customers.Count()];
CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
ParallelOptions po = new ParallelOptions();
po.MaxDegreeOfParallelism = System.Environment.ProcessorCount;

Parallel.ForEach(customers, po, async (customer, state, index) =>
{
    po.CancellationToken.ThrowIfCancellationRequested();
    var filePath = Path.Combine(_hostingEnvironment.WebRootPath, "Photos", $"{customer.CustomerNumber}.jpg");
    byte[] secondImageBytes = await System.IO.File.ReadAllBytesAsync(filePath).ConfigureAwait(false);
    ByteArrayContent secondImage = new ByteArrayContent(secondImageBytes);

    var test = await SomeFunction().ConfigureAwait(false);
    if (test)
    {
        //cancel all foreach task
    }
});
Task[]tasks=新任务[customers.Count()];
CancellationTokenSource tokenSource=新的CancellationTokenSource();
CancellationToken=tokenSource.token;
ParallelOptions po=新的ParallelOptions();
po.MaxDegreeOfParallelism=System.Environment.ProcessorCount;
Parallel.ForEach(客户、采购订单、异步(客户、状态、索引)=>
{
po.CancellationToken.ThrowIfCancellationRequested();
var filePath=Path.Combine(_hostingEnvironment.WebRootPath,“Photos”,$“{customer.CustomerNumber}.jpg”);
byte[]secondImageBytes=await System.IO.File.ReadAllByteAsync(文件路径).ConfigureAwait(false);
ByteArrayContent secondImage=新的ByteArrayContent(secondImageBytes);
var test=await SomeFunction().ConfigureAwait(false);
如果(测试)
{
//取消所有foreach任务
}
});
为了便于理解,测试代码:

  static async Task Main(string[] args)
    {
        Stopwatch watch = new Stopwatch();
        watch.Start();
        List<TaskItem> taskList = new();
        taskList.Add(new TaskItem { Id = 1, Delay = 100, isOkey = true, Name = "Try 1" });
        taskList.Add(new TaskItem { Id = 2, Delay = 2000, isOkey = false, Name = "Try 2" });
        taskList.Add(new TaskItem { Id = 3, Delay = 100, isOkey = false, Name = "Try 3" });
        taskList.Add(new TaskItem { Id = 4, Delay = 100, isOkey = false, Name = "Try 4" });
        taskList.Add(new TaskItem { Id = 5, Delay = 100, isOkey = false, Name = "Try 5" });
        taskList.Add(new TaskItem { Id = 6, Delay = 200, isOkey = false , Name = "Try 6" });
        taskList.Add(new TaskItem { Id = 7, Delay = 10000, isOkey = false, Name = "Try 7" });
        taskList.Add(new TaskItem { Id = 8, Delay = 10000, isOkey = false, Name = "Try 8" });
        taskList.Add(new TaskItem { Id = 9, Delay = 10000, isOkey = false, Name = "Try 9" });
        var control=await TestTask2Async(taskList);
        Console.WriteLine("Result ="+control);
        watch.Stop();
        Console.WriteLine(watch.Elapsed.TotalSeconds.ToString());
        Console.ReadKey();
    }
    public static async Task<int> TestTaskAsync(List<TaskItem> taskList)
    {       
        var matchedId = 0;       
        try
        {
            var tokenSource = new CancellationTokenSource();
            var token = tokenSource.Token;
            var SomeTask = Task.Factory.StartNew(async () =>
            {               
                await Task.WhenAll(taskList.AsEnumerable().Select(async item =>
                {
                    token.ThrowIfCancellationRequested();
                    await Task.Delay(100);
                    await Task.Delay(1000);
                    await Task.Delay(item.Delay);                        
                    Console.WriteLine("Process for " + item.Id);
                    if (item.isOkey)
                    {
                        Console.WriteLine("Founded " + item.Id);
                        matchedId = item.Id;                            
                        tokenSource.Cancel();                            
                    }
                }));
            },token);
            await SomeTask.Result;
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
        return matchedId;
    }


    public static async Task<int> TestTask2Async(List<TaskItem> taskList)
    {
        var matchedId = 0;
        try
        {
            var tokenSource = new CancellationTokenSource();
            var token = tokenSource.Token;
            
            await Task.WhenAll(taskList.AsEnumerable().Select(async item =>
            {
                token.ThrowIfCancellationRequested();
                await Task.Delay(100).ConfigureAwait(false); 
                await Task.Delay(1000).ConfigureAwait(false); 
                await Task.Delay(item.Delay).ConfigureAwait(false); 
                Console.WriteLine("Process for " + item.Id);
                if (item.isOkey)
                {
                    Console.WriteLine("Founded " + item.Id);
                    matchedId = item.Id;
                    tokenSource.Cancel();
                }
            }));
        }
        catch (Exception)
        {
        }
        return matchedId;
    }
  public class TaskItem
{
    public int Id { get; set; }
    public int Delay { get; set; }
    public string Name { get; set; }
    public bool isOkey { get; set; }
}
static async Task Main(字符串[]args)
{
秒表=新秒表();
watch.Start();
List taskList=new();
添加(新任务项{Id=1,Delay=100,isOkey=true,Name=“Try 1”});
添加(新任务项{Id=2,Delay=2000,isOkey=false,Name=“Try 2”});
添加(新任务项{Id=3,Delay=100,isOkey=false,Name=“Try 3”});
添加(新任务项{Id=4,Delay=100,isOkey=false,Name=“Try 4”});
添加(新任务项{Id=5,Delay=100,isOkey=false,Name=“Try 5”});
添加(新任务项{Id=6,Delay=200,isOkey=false,Name=“Try 6”});
添加(新任务项{Id=7,Delay=10000,isOkey=false,Name=“Try 7”});
添加(新任务项{Id=8,Delay=10000,isOkey=false,Name=“Try 8”});
添加(新任务项{Id=9,Delay=10000,isOkey=false,Name=“Try 9”});
var控制=等待TestTask2Async(任务列表);
Console.WriteLine(“结果=”+控制);
看,停;
WriteLine(watch.eassed.TotalSeconds.ToString());
Console.ReadKey();
}
公共静态异步任务TestTaskAsync(列表taskList)
{       
var-matchedId=0;
尝试
{
var tokenSource=new CancellationTokenSource();
var token=tokenSource.token;
var SomeTask=Task.Factory.StartNew(异步()=>
{               
等待Task.WhenAll(taskList.AsEnumerable().Select(异步项=>
{
token.ThrowIfCancellationRequested();
等待任务。延迟(100);
等待任务。延迟(1000);
等待任务延迟(项目延迟);
Console.WriteLine(“处理”+项目Id);
if(项目isOkey)
{
Console.WriteLine(“已建立”+项目Id);
matchedId=item.Id;
tokenSource.Cancel();
}
}));
},代币);
等待某项任务。结果;
}
捕获(例外e)
{
控制台写入线(e.Message);
}
返回matchedId;
}
公共静态异步任务TestTask2Async(列表任务列表)
{
var-matchedId=0;
尝试
{
var tokenSource=new CancellationTokenSource();
var token=tokenSource.token;
等待Task.WhenAll(taskList.AsEnumerable().Select(异步项=>
{
token.ThrowIfCancellationRequested();
等待任务。延迟(100)。配置等待(false);
等待任务。延迟(1000)。配置等待(false);
等待任务。延迟(item.Delay)。配置等待(false);
Console.WriteLine(“处理”+项目Id);
if(项目isOkey)
{
Console.WriteLine(“已建立”+项目Id);
matchedId=item.Id;
tokenSource.Cancel();
}
}));
}
捕获(例外)
{
}
返回matchedId;
}
公共类任务项
{
公共int Id{get;set;}
公共整数延迟{get;set;}
公共字符串名称{get;set;}
公共bool isOkey{get;set;}
}
  • 结果:

    过程4

    5年的进程

    过程1

    3年的进程

    成立1

    6年的进程

    过程2

    过程7

    过程9

    过程8

    结果=1

    11.2402357

但我想如果建立了(bla),所有的任务都将结束,我不想看到建立后(bla)的过程

对于这个示例,我只想看到:

过程4

5年的进程

过程1

3年的进程

成立1

结果=1


1.2402357

并行。ForEach
的设计不适用于
异步
-
等待

当所有项目到达第一个未完成的
wait
时,该
Parallel.ForEach
将立即终止

请尝试以下方法:

var tokenSource = new CancellationTokenSource();
var token = tokenSource.Token;

await Task.WhenAll(customers.Select(async customer =>
{
    token.ThrowIfCancellationRequested();
    var filePath = Path.Combine(_hostingEnvironment.WebRootPath, "Photos", $"{customer.CustomerNumber}.jpg");
    var secondImageBytes = await File.ReadAllBytesAsync(filePath).ConfigureAwait(false);
    var secondImage = new ByteArrayContent(secondImageBytes);

    var test = await SomeFunction().ConfigureAwait(false);
    if (test)
    {
        tokenSource.Cancel();
    }
}));
另外,不要将
Task.Factory.StartNew
async
-
wait
一起使用。使用
任务。改为运行

关于取消令牌,您需要知道的一件事是,它表示取消的意图,但它本身不会取消任何内容。代码需要检查它并以任何需要的方式取消

试试这个:

public static async Task<int> TestTask2Async(List<TaskItem> taskList)
{
    var matchedId = 0;
    try
    {
        var tokenSource = new CancellationTokenSource();
        var token = tokenSource.Token;

        await Task.WhenAll(taskList.AsEnumerable().Select(async item =>
        {
            token.ThrowIfCancellationRequested();
            // add token to the call to Task.Delay
            await Task.Delay(100, token).ConfigureAwait(false);
            await Task.Delay(1000, token).ConfigureAwait(false);
            await Task.Delay(item.Delay, token).ConfigureAwait(false);
            // check it again
            token.ThrowIfCancellationRequested();
            Console.WriteLine("Process for " + item.Id);
            if (item.isOkey)
            {
                // cancel as soon as the condition has been met
                tokenSource.Cancel();
                Console.WriteLine("Founded " + item.Id);
                matchedId = item.Id;
            }
        }));
    }
    catch (Exception ex)
    {
    }
    return matchedId;
}
公共静态异步任务TestTask2Async(列表任务列表)
{
var-matchedId=0;
尝试
{