2016-10-03 4 views
3

Я программирование игры с помощью Unity Engine и я в настоящее время работаю в следующей задачу:Сравните параметры нескольких обратных вызовов

У меня есть метод, который асинхронно возвращает его результат, используя параметры функции обратного вызова. Довольно просто, это выглядит следующим образом:

public void CalculateSomething(- PARAMETERS - , Action<float> callback) 

я должен вызвать этот метод в цикле для различных параметров.

foreach(float f in manyFloats){ 
    CalculateSomething(f, myCallback); 
} 
void myCallback(float f){ 
    ...compare this result value to the other values?... 
} 

Теперь я хотел бы сравнить полученные поплавки, которые приходят с различными обратными вызовами. Скажем так, я хочу найти наивысшую ценность среди этих поплавков. Как мне это сделать?

У меня возникла идея сохранить результаты в поле массива и просто сравнить после его полного заполнения, но я не знаю, как проверить, выполнены ли все обратные вызовы уже.

В идеале я бы хотел избежать загрязнения моего класса таким полем, но было бы хорошо, если нет другого пути.

Функция CalculateSomething является частью библиотеки, поэтому я не могу ее изменить. Все остальное является переменным.

+1

Вам нужна настройка обратного вызова, которую вы сейчас имеете? С этим примером кода кажется проще всего вернуть значение из 'CalculateSomething' для добавления в список, и вы можете сравнить значения после цикла. – Jonesopolis

+1

'CalculateSomething' из другой библиотеки, поэтому это должно остаться. Все остальное можно было бы изменить. О вашем предложении: Как узнать, когда список заполнен? Как проверить, завершен ли каждый callback? Могу ли я сделать это, не загрязняя мой класс? Редактировать: К сожалению, это не предназначалось для отправки уже ... – MaXL130

ответ

1

Это сделка. Вы правильно поняли создание массива и сохранение значений и сравнение их при выполнении всех обратных вызовов. Следовательно, проблема в том, что вы не знаете, когда возвращаются все обратные вызовы. Но вы знаете, сколько обратных вызовов существует в зависимости от количества вашего источника. manyFloats переменная. Все, что вам нужно сделать, это поддерживать счетчик и добавлять его каждый раз, когда возвращается обратный вызов. И проверьте, равно ли это числу многих флагов, и вы можете сделать сравнение:

int count = 0; 
void myCallback(float f) 
{ 
    ... usual stuff 
    ... then 
    if(count == manyFloats.Count) 
    { 
     // do the comparison 
    } 
    else 
    { 
     count ++; 
    } 
} 
+0

Это будет работать, спасибо! – MaXL130

1

Вместо использования модели на основе обратного вызова вы должны использовать модель на основе Task. Have CalculateSomething верните a Task<float> вместо обратного вызова. Это позволяет использовать TPL компоновать Task объектов путем написания кода, как:

var highestResult = (await Task.WhenAll(manyFloats.Select(CalculateSomething))).Max(); 

Если вы не можете редактировать сам метод, а затем создать свою собственную обертку, преобразующую метод в основе версию задачи.

+0

Спасибо за ваш ответ. Могу ли я это сделать без изменения 'CalculateSomething'? Дело в том, что это часть библиотеки. – MaXL130

+0

@ MaXL130 Я обратился к этому в своем последнем предложении. – Servy

+0

Да, вы сделали ... прошу пропустить это. Поэтому, я думаю, я начну больше узнавать о задачах и о том, как их использовать. – MaXL130

0

Итак, если у нас нет контроля над функцией CalculateSomething, мы по-прежнему можем хранить максимальное значение и делать сравнение в нашем обратном вызове. Что-то вроде этого:

void callbackFunction(float numb){ 
    if (numb > maxNumb) //maxNumb is global 
     maxNumb = numb; 
} 

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

Даже если вы не проводите сравнение Min/Max, и это нечто более сложное, вы все равно можете сделать это в функции обратного вызова. Нет необходимости в массивах, потому что даже с массивами, если вы можете сделать это с помощью одного прохода через массив, вы можете сделать это в функции обратного вызова.

+0

Я не могу изменить функцию 'CalculateSomething', поскольку она является частью библиотеки. Так что, наверное, это не сработает? – MaXL130

+0

Это относится ко всем [этим проблемам] (http://stackoverflow.com/questions/39836595/compare-parameters-of-multiple-callbacks-in-c-sharp#comment66963122_39836595), которые ОП упомянул в другом месте. – Servy

+0

Я обновил свой ответ, рассматривая все упомянутое выше. Я все еще верю, что это лучший способ, чем хранить все в массиве и делать буквально то же самое. – GSazheniuk

Смежные вопросы