Безопасно ли вызывать task.dispose при использовании async / await после вызова await [duplicate]

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

Python не сохраняет значения в переменных; он связывает имена с объектами. Ваше исходное назначение взяло объект, на который ссылается my_list, и связал его с new_list. Независимо от того, какое имя вы используете, остается только один список, поэтому изменения, сделанные при обращении к нему как my_list, будут сохраняться при обращении к нему как new_list. Каждый из других ответов на этот вопрос дает вам различные способы создания нового объекта для привязки к new_list.

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

new_list = list(my_list)  # or my_list[:], but I prefer this syntax
# is simply a shorter way of:
new_list = [element for element in my_list]

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

import copy  
# each element must have __copy__ defined for this...
new_list = [copy.copy(element) for element in my_list]

Это еще не глубокая копия, потому что каждый элемент списка может ссылаться на другие объекты, точно так же, как список привязан к его элементам. Чтобы рекурсивно скопировать каждый элемент в списке, а затем каждый другой объект, на который ссылаются каждый элемент, и т. Д .: выполните глубокую копию.

import copy
# each element must have __deepcopy__ defined for this...
new_list = copy.deepcopy(my_list)

Для получения дополнительной информации о копировании в окне [gg] см. документацию .

17
задан Keith Pinson 9 July 2014 в 18:40
поделиться

1 ответ

В то время как нормальное правило состоит в том, чтобы всегда вызывать Dispose() во всех реализациях IDisposable, Task и Task<T> часто являются одним из случаев, когда лучше разрешить финализатору это.

Причина Task реализует IDisposable в основном из-за внутреннего WaitHandle. Это необходимо для правильной работы задач и используется только в случае продолжения задачи. Если продолжения не существует, метод Dispose Dispose не имеет реального эффекта - поэтому в этом случае это не требуется.

Как сказано, в большинстве случаев, когда есть продолжение задачи, это часто очень, очень трудно написать свой код таким образом, чтобы вы могли правильно вызвать Dispose (). Использование операторов обычно не работает с экземплярами Task, так как вызов Task обычно является асинхронным по своей природе. Очень легко избавиться от задачи слишком рано, особенно при использовании оператора using.

Если в вашем случае относительно просто сохранить ссылку на Задачу и правильно вызвать Dispose () , Я бы сделал это. Однако, если это приведет к тому, что ваша логика станет намного сложнее, я обычно делаю вид, что Task не является IDisposable и разрешает его очищать в финализаторе для задачи.

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

18
ответ дан Reed Copsey 22 August 2018 в 04:16
поделиться
  • 1
    И ... [CodeAnalysis.SuppressMessage («Microsoft.Reliability», «CA2000», «Обоснование =» stackoverflow.com/questions/5985973/… – GarethOwen 18 June 2012 в 16:03
  • 2
    Судя по потоку Stephen Toub, на который вы ссылаетесь, я думаю, что вы сделали это назад, когда вы говорите, что «[handle wait] требуется для правильной работы продолжения задачи и используется только тогда, когда есть продолжение в Задаче. Если продолжения нет, метод Dispose Task не имеет никакого реального эффекта ... & quot; Но согласно Toub, «Task.Dispose существует из-за того, что Task потенциально обертывает дескриптор события ... Если все, что вы делаете, использует продолжения, этот дескриптор события никогда не будет выделен, а значение Dispose значительно уменьшится. & Quot; т. е. обратное тому, что вы подразумеваете выше. – Daniel Earwicker 6 September 2015 в 19:14
Другие вопросы по тегам:

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