Как мне прекратить запуск списка задач, если условие выполнено - PullRequest
0 голосов
/ 04 апреля 2019

Я делаю большое количество клиентских запросов на получение, и приведенный ниже код работает нормально, но как мне заставить принудительно завершить выполнение, как только HttpResponseMessage of StatusCode.OK найден, а затем вернуть эту единственную задачу.

  public List<Task<HttpResponseMessage>> GetUploadURLAsync(List<string> list)
        {
            List<Task<HttpResponseMessage>> tasks = new List<Task<HttpResponseMessage>>();
            using (HttpClient client = new HttpClient())
            {
                for(int i = 0; i < list.Count; i++)
                {
                  <client get async code generating task list>
                }
                Task.WaitAll(tasks.ToArray());
            }
            return tasks;
    }

Ответы [ 2 ]

1 голос
/ 04 апреля 2019

Примерно так:

class SomeClass
{
    private static HttpClient _httpClient = new HttpClient();

    public static Task<HttpResponseMessage> GetFirstSuccessAsync(List<string> list)
    {
        var tasks = new List<Task<HttpResponseMessage>>();
        foreach (var url in list) {
            tasks.Add(_httpClient.GetAsync(url));
        }

        return WhenAnySuccess(tasks);
    }

    private static async Task<HttpResponseMessage> WhenAnySuccess(List<Task<HttpResponseMessage>> tasks)
    {
        while (tasks.Count > 0) {
            Task<HttpResponseMessage> task = await Task.WhenAny(tasks);
            if (task.Status == TaskStatus.RanToCompletion && task.Result.StatusCode == HttpStatusCode.OK) {
                return task.Result;
            }

            tasks.Remove(task);
        }

        return null;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var response = SomeClass.GetFirstSuccess(new List<string> { "http://google.com", "http://microsoft.com" }).Result;
        Console.WriteLine(response.RequestMessage.RequestUri);
        Console.ReadKey();
    }
}
0 голосов
/ 04 апреля 2019

Вам понадобится CancellationTokenSource , при условии, что ваша асинхронная операция поддерживает отмену.

...