不必等待所有任务完成即可访问Enumerable.Range的结果

4
我是一位有用的助手,可以为您进行文本翻译。以下是您需要翻译的内容:

我有一个控制台应用程序,在这个应用程序中我需要访问一些url并重复200次,等待所有请求返回,然后处理这200个结果。

我使用了并行方式:

var classNameTasks = Enumerable.Range(1, 200).Select(i => webApi.getSplittedClassName()).ToArray();
string[][] splittedClassNames = await Task.WhenAll(classNameTasks);
if (splittedClassNames[0] == null)
    result = new TextResult("Error accessing the web");

getSplittedClassName返回一个string[]数组,如果网络断开它将返回null

现在,正如您所看到的,在完成所有任务后,我通过if检查内容,如果是null -> 表示网络有问题。

问题在于,在我能够检查内容之前,我需要等待全部200个请求返回。

我正在寻找一种方法,可以立即检测没有网络的情况,并返回null,而无需等待这200个请求。


1
你是否预计在任务执行期间会出现网络中断?或者你可以在开始任务之前检查网络连接吗? - Robert Harvey
强相关:https://dev59.com/0l4d5IYBdhLWcg3wDe71 - Robert Harvey
嗯,我想它可能是两个选项都有。我只是试图捕捉所有可能发生的错误。 - Ofek Agmon
我也许可以在等待所有任务完成之前完成它,但这需要更改我的代码。你会怎么做呢? - Ofek Agmon
通过完成来处理任务,(俄文)并且在github上有源代码://github.com/SergeyTeplyakov/TplTipsAndTricks - Qwertiy
显示剩余2条评论
1个回答

2
为此,您需要以下内容:
  1. A CancellationTokenSource to signal that the job is done.
  2. The WhenAll method from Tortuga.Anchor

    static async Task Test()
    {
        TextResult result;
    
        var cts = new CancellationTokenSource();
    
        var classNameTasks = Enumerable.Range(1, 200).Select(i => getSplittedClassName(cts)).ToArray();
        await classNameTasks.WhenAll(cts.Token);
        if (cts.IsCancellationRequested)
            result = new TextResult("Error accessing the web");
    
        string[][] splittedClassNames = classNameTasks.Select(t => t.Result).ToArray();
    
    }
    
    private static async Task<string[]> getSplittedClassName(CancellationTokenSource cts)
    {
        try
        {
            //real code goes here
            await Task.Delay(1000, cts.Token); //the token would be passed to the real web method
            return new string[0];
        }
        catch
        {
            cts.Cancel(); //stop trying
            return null;
        }
    }
    

这是正确的方法,尽管如果在try/catch块中取消令牌而不是抛出异常以响应空值,则更加正确(或与OP对齐)。 - shay__
我已经修复了返回值为null的问题,但我认为还存在一个bug。如果我没记错的话,await classNameTasks.WhenAll(cts.Token);会抛出一个包含OperationCanceledExceptionAggregateException异常。 - Jonathan Allen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接