7 votes

Applescript peut-il être multithreadé ?

Je suis en train d'écrire un Applescript pour Spotify qui est censé faire deux choses :

  1. Enregistrer chaque nouvelle chanson jouée.
  2. Toutes les N secondes, vérifier le périphérique sonore utilisé.

Je fais (1) par une simple boucle qui vérifie la quantité de piste restante et utilise ensuite cette valeur dans une déclaration de retard dans la boucle (il n'est pas nécessaire d'exécuter la boucle à pleine vitesse). Cependant, N est généralement bien inférieur au temps restant de la piste en cours. C'est pourquoi j'aimerais que la tâche (2) soit exécutée dans une boucle séparée avec N-0,5 comme valeur de retard. En fait, je veux que deux boucles soient exécutées simultanément à partir du même script. Est-ce possible ?

(Bien sûr, je pourrais utiliser deux scripts distincts, mais j'ai besoin de distribuer cette solution une fois qu'elle est terminée, donc une complexité visuelle moindre - c'est-à-dire deux scripts fonctionnant simultanément, prenant de la place dans le Dock, devant être lancés, etc - est préférable).

2voto

Oskar Points 1242

Pas facilement. Le concept de processus et de threads n'est pas contenu dans AppleScript.

Vous aurez besoin d'un autre outil pour ce travail. Swift pourrait être un bon outil, à moins que vous ne recherchiez Python ou quelque chose d'un peu plus établi.

2voto

Graham Miln Points 39606

Limites linguistiques

Depuis MacOS 10.13, AppleScript ne prend pas trivialement en charge le multithreading au sein d'un même script. Il semble possible d'utiliser NSThread dans un AppleScript, mais cela est complexe et entraîne une deuxième limitation, celle de l'application avec laquelle on interagit.

Limites de la demande

Outre le fait que le langage AppleScript lui-même ne représente pas nativement les threads, il est peu probable que l'application appelée traite les AppleEvents de manière optimale sur le plan des threads. Les AppleEvents sont mis en file d'attente par MacOS dans l'ordre "premier entré, premier sorti" (FIFO) pour être traités par l'application.

L'application peut différer les réponses aux AppleEvents de longue durée, mais cela nécessite une ingénierie supplémentaire que peu d'applications mettent en œuvre. La plupart des applications se bloquent jusqu'à ce que l'AppleEvent soit traité avant de s'intéresser à l'AppleEvent suivant.

Cela signifie qu'un AppleScript multithreads communiquant avec une seule application n'obtiendrait probablement pas les gains de performance escomptés pour l'effort fourni.

Boucle à événement unique ?

Vous pourriez aborder le problème avec une seule boucle traitant plusieurs événements. La boucle unique pourrait dormir pendant N secondes, se réveiller et traiter les tâches appropriées en attente.

Réponse de Piyomaru montre une façon de mettre en œuvre une approche basée sur les événements. Cette approche n'est pas multithreadée ou parallèle ; il s'agit d'une boucle événementielle.

1voto

Max Points 11

AppleScript maintenant supporte le multithreading (MacOS 10.10 ou ultérieur). Il dispose à l'origine d'une fonction d'interruption de temporisation depuis 1993 ( on idle fonctionne simultanément dans un seul AppleScript).

J'ai écrit quelques AppleScripts avec iTunes comme vous l'avez écrit. AppleScript peut créer des délégués et recevoir des événements d'autres applications.

Cet exemple d'AppleScript peut recevoir le changement d'état de lecture d'iTunes. Une fois que le script est exécuté dans script Editor, il reçoit l'événement de changement de lecture d'iTunes et affiche le nom de la piste dans la boîte de dialogue de notification de MacOS.

-- Created 2017-10-13 by Takaaki Naganoya
-- 2017 Piyomaru Software

use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property NSDistributedNotificationCenter : a reference to current application's NSDistributedNotificationCenter

on run
    NSDistributedNotificationCenter's defaultCenter()'s addObserver:me selector:"statusChanged:" |name|:"com.apple.iTunes.playerInfo" object:(missing value)

end run

on statusChanged:sender
    tell application id "com.apple.iTunes"
        try
            tell current track
                set anAlbum to album
                set aName to name
                set anArtist to album artist
                set aRating to rating
            end tell
        on error
            return
        end try
    end tell
    display notification aName
end statusChanged:

La question est donc de savoir si l'application Spotify peut fournir une telle fonction comme iTunes ou non.

0voto

Marián Černý Points 296

Je suggère d'écrire cela en JavaScript plutôt qu'en AppleScript. JavaScript est un langage pris en charge pour les scripts d'événements Apple. JavaScript est monotâche, mais il est beaucoup plus facile d'écrire du code asynchrone non bloquant.

setInterval(function() {
    console.log('Do something in the closure function here');
}, 3000);

LesApples.com

LesApples est une communauté de Apple où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres utilisateurs d'appareils Apple, poser vos propres questions ou résoudre celles des autres.

Powered by:

X