Используя повышение встроенной системы с ограничением памяти

Есть два решения. Быстрым и грязным было бы добавить счетчик, чтобы указать количество оставшихся заданий, которое будет увеличиваться, как и до вызова 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, где бы вы ни вызывали этот метод, либо иметь другой обратный вызов для обработки завершения

9
задан Nicolas 3 October 2008 в 12:18
поделиться

5 ответов

Вы могли записать свое собственное средство выделения для контейнера, который выделяет от фиксированного размера статический буфер. В зависимости от шаблонов использования контейнера средство выделения могло быть столь же простым как постепенное увеличение указателя (например, когда Вы только вставляете материал в контейнер однажды при запуске приложения и непрерывно не добавляете/удаляете элементы.)

6
ответ дан 4 December 2019 в 09:14
поделиться

Мы используем повышение для встроенных систем. С повышением можно привередливо выбрать то, что Вы используете. Мы используем smart_ptr и boost::bind во всех наших проектах. Мы пишем программное обеспечение для дешевых сотовых телефонов. И если бы Windows CE может работать на Ваших аппаратных средствах, я ожидал бы, что части повышения были бы применимы. Существуют части повышения, которые не имеют никакого выделения, и Вы могли бы найти их полезными.

Я привередничал бы на основе Ваших требований.

Как что-либо, что Вы используете, необходимо знать затраты.

14
ответ дан 4 December 2019 в 09:14
поделиться

Замена Ваших контейнеров с контейнерами Повышения НЕ является хорошей идеей. Работа для создания соответствующих пользовательских средств выделения не состояла бы в том, что плохо, но Вы будете нарушать дух Ваш, 'выделяют при запуске' правило. Идея позади этого правила (по моему опыту), состоит в том, чтобы обычно удостоверяться, что Вы не должны иметь дело с из ситуаций с типом памяти во времени выполнения. Идея состоит в том, чтобы удостовериться, что у Вас есть вся память, в которой Вы могли возможно нуждаться прямо В ЗАПУСКЕ, так, чтобы не было никакой возможности никакой части системы, подходящей за исключением памяти позже.

При использовании контейнеров Повышения с пользовательским средством выделения необходимо было бы внезапно иметь дело с возможностью, что пул, от которого выделяет контейнер, мог пойти пустой, таким образом устранение цели 'выделяет при запуске' правило.

В ситуации устройства ограниченной памяти я избежал бы любого вида контейнера, более сложного, чем статически выделенный массив.

2
ответ дан 4 December 2019 в 09:14
поделиться

Повышение является рядом библиотек. Некоторые из них фокусируются на шаблонном метапрограммировании. Они даже не используют памяти во времени выполнения. Но Ваш вопрос, кажется, о замене Ваших контейнеров. Я сомневался бы, что это возможно кроме использования пользовательских средств выделения. Но даже затем, наиболее вероятно, что Вы использовали бы плоскость контейнеры STL и не повышение. Повышение только обеспечивает контейнеры TR1 для тех компиляторов, которые еще не включают TR1.

1
ответ дан 4 December 2019 в 09:14
поделиться

Не используйте Повышение.

Это - крупная библиотека, и Ваши требования выделения основной памяти очень отличаются от тех из разработчиков библиотек.

Даже если можно заставить текущую версию Повышения работать согласно требованиям с пользовательскими средствами выделения, оно может порвать с новой версией Повышения.

Не стесняйтесь смотреть на исходный код Повышения, хотя для некоторых полезных идей, но используют Вашу собственную реализацию для того, в чем Вы нуждаетесь.

0
ответ дан 4 December 2019 в 09:14
поделиться
Другие вопросы по тегам:

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