У меня есть список URL-адресов. Я запускаю OpenreadAsync (url1) для OpenReadAsync (url) .. Как мне ждать завершения всех из них

Следующий код заменит значения NA в соответствии с тестом Shapiro:

library(dplyr)

data %>% 
 group_by(sex) %>%
 mutate(
  emotion = ifelse(!is.na(emotion), emotion,
   ifelse(shapiro.test(emotion)$p.value > 0.05,
    mean(emotion, na.rm=TRUE), quantile(emotion, na.rm=TRUE, probs=0.5) ) ),
  IQ = ifelse(!is.na(IQ), IQ,
   ifelse(shapiro.test(IQ)$p.value > 0.05,
    mean(IQ, na.rm=TRUE), quantile(IQ, na.rm=TRUE, probs=0.5) )
  )
 ) 
0
задан swifty 19 January 2019 в 10:43
поделиться

1 ответ

Есть два решения. Быстрым и грязным было бы добавить счетчик, чтобы указать количество оставшихся заданий, которое будет увеличиваться, как и до вызова GetResponse, и уменьшаться в рамках обратного вызова, а если оно достигнет 0, вызовите следующий шаг в вашем процессе. Это было бы рискованно из-за состояния состязания и непредсказуемого поведения потока, например, если вы вызываете один запрос и до того, как начнется второй запрос, а затем он попытается продолжить.

Лучшим решением было бы отслеживать порожденные Задачи, используя OpenReadTaskAsync вместо OpenReadAsync, а затем использовать Task.WhenAll({ALL YOUR TASKS}).

Это немного изменит вашу программу:

List<Result> result = new List<Result>();
List<Task<Stream>> jobs = new List<Task<Stream>>();

...

GetResponse пришлось бы возвращать значение задачи, которое является простым.

private Task<Stream> GetResponse(Uri uri, Action<MyResponse> callback)
{
  ... //Almost all of your code stays the same, 
      //though you should close the stream you receive in the OnReadCompleted callback.
  return m_webClient.OpenReadTaskAsync(uri.ToString());
}

Последний в методе FillResults, вы должны добавить эти задачи в список и ждать.

public async Task FillResults()
{
      foreach( var urlx in Urls)
      {
            jobs.Add(
                      GetResponse(urlx, (response) =>
                      {
                        if (response != null && response.StatusCode==200)
                        {
                            Result result=new Result;
                            result.Value=response.SomeValue;
                            result.url=urlx;------>It is important that SomeValue corresponds to urlx and not other say,urly
                            results.Add(result);
                        }
                      })
                   );
      }

      await Task.WhenAll(jobs);

      //Or Task.WhenAll(jobs).ContinueWith({AN ACTION CALLBACK}) 
      //if you want to keep the return as a void;
}

Теперь вы можете либо ожидать функцию FillResults, где бы вы ни вызывали этот метод, либо иметь другой обратный вызов для обработки завершения

0
ответ дан MiltoxBeyond 19 January 2019 в 10:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: