Если я правильно понимаю ваш вариант использования, вы можете использовать TaskCompletionSource.
Пример реализации:
public class AsyncCache
{
private Dictionary<Guid, Task<string>> _cache;
public Task<string> GetAsync(Guid guid)
{
if (_cache.TryGetValue(guid, out var task))
{
// The value is either there or already queued
return task;
}
var tcs = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
_queue.Enqueue(() => {
var result = LoadResult();
tcs.TrySetValue(result);
});
_cache.Add(guid, tcs.Task);
return tcs.Task;
}
}
Здесь _queue
- это любой механизм организации очередей, который вы собираетесь использовать для обработки данных. Конечно, вам также придется сделать этот код поточно-ориентированным.
Цикл foreach не будет работать на этот случай. Вы не можете использовать цикл foreach для инициализации массива. Ваш код:
int[] array = new int[5];
for (int i : array) {
i = 24;
}
переведет во что-то как следующее:
int[] array = new int[5];
for (int j = 0; j < array.length; j++) {
int i = array[j];
i = 24;
}
Если бы это было массивом объектов, то он все еще перестал бы работать. В основном для - каждый присваивает каждую запись в наборе или массиве, в свою очередь, к переменной, которую Вы обеспечиваете, с которым можно затем работать. Переменная не эквивалентна ссылке на массив. Это - просто переменная.
Для - каждый не может использоваться для инициализации любого массива или Набора, потому что он циклично выполняется по текущему содержанию массива или Набора, давая Вам каждое значение по одному. Переменная в для - каждый не прокси для ссылки Набора или массива. Компилятор не заменяет Ваш"i
"(от"int i
") с"array[index]
".
Если Вы имеете массив Даты, например, и пробуете это, код:
Date[] array = new Date[5];
for (Date d : array) {
d = new Date();
}
был бы переведен во что-то вроде этого:
Date[] array = new Date[5];
for (int i = 0; i < array.length; i++) {
Date d = array[i];
d = new Date();
}
который, как Вы видите, не инициализирует массив. Вы закончите с массивом, содержащим всех, аннулирует.
Примечание: Я взял код выше, скомпилировал его в a .class
файл и затем используемый вруб для декомпиляции его. Этот процесс дает мне следующий код, сгенерированный компилятором Java Sun (1.6) из кода выше:
int array[] = new int[5];
int ai[];
int k = (ai = array).length;
for(int j = 0; j < k; j++)
{
int i = ai[j];
i = 5;
}
i
просто копия интервала в той точке в массиве, не ссылка на него. Цикл foreach не работает в этом случае.
Использовать
java.util.Arrays.fill(array, 24)
если Вы собираетесь быть инициализацией к тому же значению. Кроме этого, Eddie является в значительной степени точечным на в его переводе для - каждая конструкция.
интервал является типом примитива в системе, таким образом, Вы на самом деле получаете копию значения ячейки в массиве, а не ссылку на ту ячейку в массиве, в который можно присвоиться....
Позвольте мне попытаться объяснить это. Если бы у Вас был массив Xs, где X класс, который имеет элементы данных, Вы получили бы ссылку на другую ячейку в каждом повторении и смогли бы изменить его состояние путем вызывания функций на нем (например, setValue).
Когда у Вас есть ints, это - другая история, Ваш интервал не является ссылкой, это - фактическое значение на стеке, так как это - тип примитива, таким образом, в каждом повторении, для копий значение от массива в меня. Вы затем обновляете Ваш я, но это не имеет никакого эффекта на массив.
Сделайте это вместо этого:
int[] array = new int[5];
// initialise array -> Will work now
for(int i = 0 ; i< array.length ; i++)
array[i] = 24 ;