# Stop/terminate a (sub)task started with @async

**URL:** https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193
**Category:** General Usage
**Tags:** question, task
**Created:** [December 12, 2019, 12:29pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193 "2019-12-12T12:29:07Z")
**Posts on this page:** 17
**Page:** 1

<div class="post-metadata">

### Author: ![stakaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stakaz/32/4740_2.png) [@stakaz](https://discourse.julialang.org/u/stakaz)
#### Post date: [December 12, 2019, 12:29pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/1 "2019-12-12T12:29:07Z")

</div>

Hello, I search a bit here and on the web and found out that obviously there is no “official” way to terminate a started task in julia yet.

However, throw an Interruption error seems to work as a workaround for now.

But now I would like to do it from within a function. Here is the example.  
The stating case is working but the stopping case is not.

```julia
function switch_timer(switch)
	if switch
	global t = @async while true
			sleep(1)
		end
	else
		@eval :(Base.throwto(t, InterruptException()))
	end
	return 
end

```

Does someone has a nice idea on how to bring it to work? Thanks

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [December 12, 2019, 12:48pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/2 "2019-12-12T12:48:19Z")

</div>

Remove the quoting after `@eval`, (the `:( ... )` part).

Right now you just evaluate a value which is an expression:

```julia
julia> b = @eval :(Base.throwto(t, InterruptException()))
:(Base.throwto(t, InterruptException()))

```

---

<div class="post-metadata">

### Author: ![stakaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stakaz/32/4740_2.png) [@stakaz](https://discourse.julialang.org/u/stakaz)
#### Post date: [December 12, 2019, 1:13pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/3 "2019-12-12T13:13:47Z")

</div>

Ups, sometimes it is the easiest stuff which one oversees. After several hours of trying different solutions for my task I finally made a trivial mistake 😉 Thanks…

---

<div class="post-metadata">

### Author: ![stakaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stakaz/32/4740_2.png) [@stakaz](https://discourse.julialang.org/u/stakaz)
#### Post date: [December 12, 2019, 1:57pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/4 "2019-12-12T13:57:04Z")

</div>

EDIT: the answer was to use `@async` for the `throwto`.

One more thing here, when I try to call the function through a toggle in a Blink window, the turning on works but turning off does not. It freezes and the REPL becomes irresponsible.

Here is the code

```julia
using Blink
using Interact

const run_toggle = toggle(label = "run") |> onchange

const timer = Observable(0.0)

function switch_timer(switch)
	if switch
	global t = @async while true
			sleep(1 / 20)
			timer[] += 1 / 20
		end
	return
	else
		@async Base.throwto(t, InterruptException())
	return
	end
end

on(switch_timer, run_toggle)

widget = vbox(hbox(run_toggle))

window = Window()
body!(window, widget)

```

---

<div class="post-metadata">

### Author: ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)
#### Post date: [December 15, 2019, 3:34am UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/5 "2019-12-15T03:34:26Z")

</div>

Yes, that might work sometimes, but you’re messing with the internal state of the scheduler, so it’s not really safe. But you’re just controlling the wrong object: `sleep` is just a thin wrapper around `Timer` and the `Timer` object does support start and stop (actually it maybe just exports the `new` and `close` actions right now, but it could export the `start` and `stop` names too).

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [December 15, 2019, 3:47am UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/6 "2019-12-15T03:47:10Z")

</div>

Is using `schedule(t, InterruptException(), error=true)` instead of `@async Base.throwto(t, InterruptException())` correct here?

---

<div class="post-metadata">

### Author: ![stakaz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stakaz/32/4740_2.png) [@stakaz](https://discourse.julialang.org/u/stakaz)
#### Post date: [December 16, 2019, 10:31am UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/7 "2019-12-16T10:31:12Z")

</div>

In this case using start and stop would be great, thanks… However, I would also like to have a possibility to stop a general task without throwing an `InterruptExeption` which looks a bit awkward to me here.

---

<div class="post-metadata">

### Author: ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)
#### Post date: [December 16, 2019, 3:51pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/8 "2019-12-16T15:51:29Z")

</div>

No, there’s no generally safe way to interrupt a task. But you can interrupt any waitable object (by closing it).

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [December 16, 2019, 4:02pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/9 "2019-12-16T16:02:08Z")

</div>

Unlike `Base.throwto`, `schedule` is a public API. If it is not safe to use, could you document this? From its docstring, I think it’s impossible for users (like me) to know that it’s an unsafe API:

[https://docs.julialang.org/en/latest/base/parallel/#Base.schedule](https://docs.julialang.org/en/latest/base/parallel/#Base.schedule)

---

<div class="post-metadata">

### Author: ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)
#### Post date: [December 16, 2019, 4:16pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/10 "2019-12-16T16:16:21Z")

</div>

That’s true, it lacks a mention that only the owning queue responsible for managing that task should call that method (and calling that method transfers ownership to a new queue)

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [December 16, 2019, 4:23pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/11 "2019-12-16T16:23:13Z")

</div>

Thanks. Does it mean that, as a user, it is valid to call `schedule(t, exception, error=true)` only if the task is not scheduled yet, like this?

```julia
julia> t = @task nothing
Task (runnable) @0x00007f3b6dd9cc40

julia> schedule(t, InterruptException(), error=true)
Task (failed) @0x00007f3b6dd9cc40
InterruptException:

```

---

<div class="post-metadata">

### Author: ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)
#### Post date: [December 16, 2019, 4:38pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/12 "2019-12-16T16:38:36Z")

</div>

Right, if you just made the task, that’s an example of when you own it. You also usually own `current_task()` (which is good, because `wait` and `yield` etc. will implicitly take ownership of it), so you can also de-schedule yourself (e.g. call `wait()`), or throw exceptions (`schedule(error=true); wait()`, or, erm, `throw()`), and implement alternate schedulers (i.e. call `wait` on something that’s not a Condition object)

---

<div class="post-metadata">

### Author: ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)
#### Post date: [December 16, 2019, 5:06pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/13 "2019-12-16T17:06:50Z")

</div>

> [@jameson](#):
>
> You also usually own `current_task()`

When is it useful to use `schedule(current_task(), exception, error=true)` instead of `throw(exception)`?

---

<div class="post-metadata">

### Author: ![jameson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jameson/32/23_2.png) [@jameson](https://discourse.julialang.org/u/jameson)
#### Post date: [December 16, 2019, 6:58pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/14 "2019-12-16T18:58:57Z")

</div>

That’s seems unlikely to ever be useful

---

<div class="post-metadata">

### Author: ![Ahmed\_Salih](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ahmed_salih/32/206579_2.png) [@Ahmed\_Salih](https://discourse.julialang.org/u/Ahmed_Salih)
#### Post date: [August 28, 2022, 8:09am UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/15 "2022-08-28T08:09:01Z")

</div>

> [@stakaz](#):
>
> `@async Base.throwto(t, InterruptException())`

None of this works anymore? I cannot stop the following task:

```julia
using BetterFileWatching
watch_task = @async watch_folder(".") do event
    @info "Something changed!" event
end

sleep(5)

# stop watching the folder
schedule(watch_task, InterruptException(); error=true)

```

In Julia 1.8

Kind regards

---

<div class="post-metadata">

### Author: ![attdona](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/attdona/32/15859_2.png) [@attdona](https://discourse.julialang.org/u/attdona)
#### Post date: [September 14, 2022, 2:51pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/16 "2022-09-14T14:51:44Z")

</div>

This is not a julia 1.8 problem but instead an issue with the package `BetterFileWatching.jl`.

The culprit is the line:

```julia
try wait(watch_task) catch; end

```

at [BetterFileWatching.jl/BetterFileWatching.jl at main · JuliaPluto/BetterFileWatching.jl · GitHub](https://github.com/JuliaPluto/BetterFileWatching.jl/blob/main/src/BetterFileWatching.jl#L123:)

When you schedule an `InterruptException()` you silently interrupt the `wait` of the `watch_task` async task but not the `watch_task` task that outlives `watch_folder`.

This is a simplified version that shows the same issue:

```julia
function watch_task()
    while true
        @info "doing something ..."
        sleep(3)
    end
    
end

function watch_folder()
    t = @async watch_task()
    try wait(t) catch; end
end

task = @async watch_folder()

sleep(5)

schedule(task, InterruptException(), error=true)

```

Eventually consider to open a `BetterFileWatchingIssue.jl` github issue …

Greetings, Attilio

---

<div class="post-metadata">

### Author: ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)
#### Post date: [September 15, 2022, 3:11pm UTC](https://discourse.julialang.org/t/stop-terminate-a-sub-task-started-with-async/32193/17 "2022-09-15T15:11:20Z")

</div>

@attdona it would be better to create a new topic rather than continuing a solved one.
