Swift AsyncStream печатает ошибку при вызове Finish() из параллельной задачи/DispatchQueue на игровой площадкеIOS

Программируем под IOS
Ответить
Anonymous
 Swift AsyncStream печатает ошибку при вызове Finish() из параллельной задачи/DispatchQueue на игровой площадке

Сообщение Anonymous »

Я экспериментирую с AsyncStream в Swift Playground и наблюдаю противоречивое поведение при вызове continue.finish().
Я создаю значения асинхронно, используя Task.sleep или DispatchQueue.asyncAfter. Если я вызову Finish() после получения последнего значения (), Playground вылетает с сообщением «выполнение остановлено с неожиданным состоянием».
Если я закомментирую Finish(), сбой исчезнет, ​​но deinit никогда не вызывается.
Вот упрощенная версия моего кода:

Код: Выделить всё

import Foundation

class Demo {
func getAsyncStream(_ doUseTask: Bool = false) -> AsyncStream {
AsyncStream { continuation in
for i in 1...5 {
if doUseTask {
Task {
try await Task.sleep(for: .seconds(i))
continuation.yield(i)
// What I am thinking, Ideally I have to do this after yield is succesful, but there is no callBack
if i == 5 {
// If I comment this out, the error disappears but deinit is not printed;
// otherwise,   deinit prints and the error still exists.
continuation.finish()
}
}
} else {
DispatchQueue.global().asyncAfter(deadline: .now() + .seconds(i)) {
continuation.yield(i)
if i == 5 {
// If I comment this out, the error disappears but deinit is not printed;
// otherwise,   deinit prints and the error still exists.
continuation.finish()
}
}
}
}
}
}

init() { print("initialised") }
deinit { print("deinitialised") }
}

do {
let demo = Demo()
for await value in demo.getAsyncStream(true) {
print(value)
}
}
Наблюдаемое поведение:
Вызов Finish() показывает ошибку на игровой площадке.
Удаление Finish() предотвращает ошибку, но deinit никогда не печатается.
Вопросы:
Почему вызов Finish() от параллельных производителей вызывает сбой?
Почему i == 5 не является безопасным способом определения момента окончания потока?
Каков правильный шаблон для безопасного вызова Finish() при асинхронном создании значений?
Это поведение характерно для Swift Playgrounds или оно будет наблюдаться и в реальном приложении?>

Подробнее здесь: https://stackoverflow.com/questions/798 ... -task-disp
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»