Как я получаю индекс объекта в Для Каждого … Следующий цикл?

Вы не должны писать асинхронные оболочки для синхронных методов , но вы также не должны писать синхронные оболочки для асинхронных методов - это и антипаттерны.

Подсказка: «естественно асинхронный» в основном означает на основе ввода / вывода, за некоторыми исключениями. Одним из таких исключений, к сожалению, являются некоторые операции с файловой системой, в том числе перемещение файлов, которые должны быть асинхронными, но API не поддерживают асинхронность, поэтому мы должны притворяться, что она синхронная.

В вашем случае DownloadToCache определенно является асинхронным. В этих случаях я предпочитаю выставлять только асинхронный API .

Если вы должны (или действительно хотите ) также поддерживать синхронный API, я рекомендую взломать логический аргумент . Семантика заключается в том, что если вы передадите sync:true, то возвращаемое задание уже выполнено. Это позволяет вам сохранять логику в одном методе и писать очень маленькие оболочки без ошибок, обычно связанных с этими оболочками:

private static async Task DownloadToCacheAsync(bool sync)
{
  ...do some analysis to get download locations...
  using (var wc = new WebClient())
  {
    if (sync)
      wc.DownloadFile(new Uri(content.Url), targetPath);
    else
      await wc.DownloadFileTaskAsync(new Uri(content.Url), targetPath);
  }
  ...do other stuff...
}
public static Task DownloadToCacheAsync() => DownloadToTaskAsync(sync: false);
public static void DownloadToCache() => DownloadToTaskAsync(sync: true).GetAwaiter().GetResult();

7
задан Simon 15 October 2008 в 19:02
поделиться

6 ответов

Индекс не имеет никакого значения к IEnumerable, который является тем, что foreach создают использование. Это важно потому что foreach может не перечислить в индексном порядке, если Ваш конкретный тип набора реализует IEnumerable нечетным способом. Если у Вас есть объект, к которому может получить доступ индекс, и Вы заботитесь об индексе во время повторения, то Вы более обеспечены просто использование традиционного для цикла:

for (int i=0;i<MyProperty.PropertyActors.Length;i++)
{
    //...
}
12
ответ дан 6 December 2019 в 05:39
поделиться

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

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

12
ответ дан 6 December 2019 в 05:39
поделиться

Могло бы быть самым легким просто сохранить отдельный счетчик:

i = 0
For Each PropertyActor As JCPropertyActor In MyProperty.PropertyActors
    ...
    i = i + 1
Next

Как в стороне, Python имеет удобный способ сделать это:

for i, x in enumerate(a):
    print "object at index ", i, " is ", x
6
ответ дан 6 December 2019 в 05:39
поделиться

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

Dim i as Integer 
For Each PropertyActor As JCPropertyActor In MyProperty.PropertyActors
    i++
Next
2
ответ дан 6 December 2019 в 05:39
поделиться

Добавьте индексную переменную, которую Вы увеличиваете сами для каждого повторения?

1
ответ дан 6 December 2019 в 05:39
поделиться

Вы могли использовать метод "FindIndex".

MyProperty.PropertyActors.FindIndex(Function(propActor As JCPropertyActor) propActor  = JCPropertyActor)

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

Dim PropertyActor As JCPropertyActor
For i As Integer = 0 To MyProperty.PropertyActors.Count - 1
    PropertyActor = MyProperty.PropertyActors.Item(i)
Next
1
ответ дан 6 December 2019 в 05:39
поделиться
Другие вопросы по тегам:

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