es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

La tarea Swift no se está ejecutando en el actor principal como se esperaba.

Tengo el siguiente código en un proyecto de prueba simple para Mac:

@main
class AppDelegate: NSObject, NSApplicationDelegate {
  func applicationDidFinishLaunching(_ aNotification: Notification) {
    print("estamos inicialmente en el hilo principal: (Thread.isMainThread)")

Task {
  print("¿es la tarea nueva en el hilo principal?: \(Thread.isMainThread)")
}

}
}

En la guía de lenguaje Swift, veo lo siguiente:

Para crear una tarea no estructurada que se ejecute en el actor actual, llame al inicializador Task.init(priority:operation:). Para crear una tarea no estructurada que no sea parte del actor actual, conocida más específicamente como tarea desvinculada, llame al método de clase Task.detached(priority:operation:).

Por lo tanto, dado que el código de AppDelegate se está ejecutando en el actor principal y estoy creando una tarea normal (es decir, no desvinculada), esperaría que su tarea secundaria también se ejecute en el actor principal.

Pero eso no es lo que sucede cuando ejecuto esta aplicación de prueba:

estamos inicialmente en el hilo principal: true
¿es la tarea nueva en el hilo principal?: false

Según lo que he leído sobre la concurrencia en Swift, esperaba que la nueva tarea fuera programada y ejecutada en el actor principal y que, por lo tanto, Thread.isMainThread fuera verdadero dentro de esa tarea.

¿Por qué no es así?

Tags:  ,

Answer

  1. Avatar for davy.ai

    La razón por la que la nueva tarea no está programada y se ejecuta en el actor principal en este caso específico es porque Task no implica necesariamente la ejecución en el hilo o actor principal.

    Según la documentación de la API de Task, una tarea puede asociarse con un actor, pero no es obligatorio. En el ejemplo de código proporcionado, la nueva tarea creada usando Task no tiene un actor asociado y, por lo tanto, se ejecuta en un hilo diferente, por lo que Thread.isMainThread devuelve false.

    Para asegurarse de que la nueva tarea se ejecute en el actor principal, es necesario asociarla explícitamente con el actor principal usando Task.init(priority: operation: associatedWith :), de la siguiente manera:

    Task(priority: .userInitiated, operation: {
        print("es la nueva tarea en el hilo principal: \(Thread.isMainThread)")
    }, associatedWith: Task.currentActor)
    

    Esto creará una nueva tarea con una asociación al actor principal, asegurándose de que se ejecute en el hilo principal y que Thread.isMainThread devuelva true.

Comments are closed.