if SHOULD_CRASH then
local thread = task.delay(totalPlayTime, SoundSystem.StopSFX, sound.Name, sound.Parent)
sound.Destroying:Connect(function()
task.cancel(thread)
end)
else
task.delay(totalPlayTime, SoundSystem.StopSFX, sound.Name, sound.Parent)
end
it seems like cancelling a thread that is already finished will crash the application
Expected Behavior
for the engine not to crash from the script
Actual Behavior
but the engine crashes from the script
Issue Area: Engine Issue Type: Crashing Impact: High Frequency: Constantly Date First Experienced: 2022-04-08 00:04:00 (+07:00) Date Last Experienced: 2022-04-08 00:04:00 (+07:00) A private message is associated with this bug report
Thanks for the report, looks like it’s actually caused by cancelling a parent thread from a child thread. This should error instead of crashing. I’ll have a fix for it soon.
I just ran into this problem as well. I’m really confused why this should be erroring because cancelling the thread is not an issue (in this scenario) until doing it after the thread has finished.
In the given example the thread has not actually finished. The delayed function StopSFX calls Destroy on the sound instance which invokes the Destroying event. This is effectively the same as doing the following:
local bindable = Instance.new("BindableEvent")
local thread = task.delay(1, function ()
bindable:Fire() -- calls task.cancel on this thread which is currently active
end)
bindable.Event:Connect(function ()
task.cancel(thread)
end)
Meanwhile the following works as you would expect:
local thread = task.delay(1, print, "Resumed")
task.wait(2)
task.cancel(thread)
print("Finished")
Yeah I can get the crash to occur with this tiny code block
task.spawn(function(thread)
task.cancel(thread)
end, coroutine.running()) -- Parent thread status is set to "normal"
print() --only crashes on the command line + some other places when running extra code after
It’s a weird bug because replacing task.cancel() with coroutine.close() throws an error that normal threads can’t be closed but task.cancel() just crashes
That should be the expected result when using task.cancel as well since they function basically identically
Hey there - still running into this issue. My testing also confirms the crash doesn’t occur if you attempt to cancel the thread normally, but it does when trying to cancel the thread from a child thread.
This errors normally:
local Thread
Thread = task.defer(function()
task.cancel(Thread)
print("Thread has run!")
end)
cannot cancel running thread
However, this crashes studio:
local Thread
Thread = task.defer(function()
task.spawn(function() task.cancel(Thread) end)
print("Thread has run!")
end)
Something curious I’ve found is that, for the crash to occur, the thread must have something pending. That’s why I included the print at the end of the function. Otherwise, the crash won’t occur and no errors will happen. This code runs without crashes or errors:
local Thread
Thread = task.defer(function()
task.spawn(function() task.cancel(Thread) end)
end)
The reason why I use task.defer() by the way, is because if I use task.spawn(), it will not yet have returned by when I try to cancel the thread and Thread will be nil.
As a suggestion/question, why does cancelling a thread within itself have to error? Is there a reason why cancelling a thread within itself can’t just stop the thread as if the thread had hit a return?
A use case I’ve had for cancelling threads within themselves is a loading screen where the user may wait for everything to load (the load happens inside a thread) or press the skip button (which cancels this thread). If they press skip, a function FinishLoading() is run which cancels the loading screen thread, and goes on to the menu. If the loading screen ends, the same function is run. But I can’t do this because the loading thread can’t canel itself, meaning I have to cancel the thread separately and can’t just include it in the FinishLoading() function.
I just found out about the bug, really tedious to deal with. I spent hours debugging! Disabling chunk of codes and a lot of stuff around to see what was causing it. Until I saw it was a bug from the Engine.
Could you guys please fix it. I don’t know how it works in the background, but assuming that coroutine.close does the same EXACT thing as task.cancel. I don’t know why is taking long to be fixed. I would assume it got pushed because coroutine.close exists.
If there is any other reason behind the fix taking long, I don’t want any response from anyone telling me that is not as easy as I expect.
Code Producing The Bug:
local Thread = coroutine.running()
local Timer = task.delay(10, function()
task.spawn(Thread)
end)
coroutine.yield()
task.cancel(Timer)
There is a fix for this but we want to explore whether we can eliminate the error entirely and make this cancel all threads before locking in the behavior.