2016-11-26 5 views
1

erwarten würde ich bei dieser Präsentation habe mir https://github.com/indyscala/scalaz-task-intro/blob/master/presentation.md und war über eines der Code-Schnipsel verwirrt es Task.runAsyncInterruptibly präsentiert mit (leicht erscheint unten modifiziert):fragen, warum scalaz Task.runAsyncInterruptibly Unterbrechung nicht, wie ich es zu

import java.util.concurrent.atomic.AtomicBoolean 

import scalaz.concurrent.Task 
import scalaz.{-\/, \/-} 

object Junk extends App { 

    val neverMind = new AtomicBoolean(false) 
    System.out.println(s"neverMind set to $neverMind on thread ${Thread.currentThread().getName}") 

    val t = Task { 
    System.out.println(s" in task run block on thread ${Thread.currentThread().getName}") 
    Thread.sleep(4000) 
    System.out.println(s" completed sleep of 40000 ms on thread ${Thread.currentThread().getName}") 
    } 

    Task.fork(t). 
    //t. 
    runAsyncInterruptibly({ 
    case -\/(t) => t.printStackTrace() 
    case \/-(()) => println(s"Completed (right) branch of case on thread ${Thread.currentThread().getName}") 
    }, neverMind) 


    println("sleeping 1000, then set nevermind to true") 
    Thread.sleep(1000) 
    neverMind.set(true) 
    println("woke up. set cancel=true -- expect stack trace not 'Completed' message") 

    Thread.sleep(4000) 

} 

Ich bin verwirrt, weil ich die "Abbrechen" -Flag (NeverMind.set (true)), aber ich sehe keinen Stack-Trace. Der Code-Block innerhalb der Verzögerung {...} gibt schließlich "erfolgreich abgeschlossen" aus. Das ist so einfach, ich bin mir sicher, dass ich einen dummen Fehler mache .. nicht sicher, wo!

Ich habe Rat von einigen Kollegen gesucht, die darauf hinwiesen, dass mein ursprüngliches Beispiel Task.fork() nicht verwendet hat, also habe ich alles auf dem gleichen Thread gemacht ... doh! OK. Das habe ich korrigiert. und es funktioniert immer noch nicht.

Vielen Dank im Voraus für jede Anleitung, die Sie zur Verfügung stellen können.

Antwort

1

Ich denke, die Antwort hat mit dem trampolining innerhalb scalaz Task/Zukunft zu tun, da es nur cancel zwischen den Schritten überprüft (siehe listenInterruptibly innerhalb scalaz des Future

Wenn Sie die Aufgabe zu ändern.

val t = Task.delay(System.out.println(s" in task run block on thread ${Thread.currentThread().getName}")) 
.map(_ => Thread.sleep(4000)) 
.map(_ => System.out.println(s" completed sleep of 40000 ms on thread ${Thread.currentThread().getName}")) 

Sie werden sehen, es wird abgebrochen, bevor der "abgeschlossene Schlaf" Schritt. Es schien noch nicht den Handler, der die Stapel-Trace, aber drucken.