Thread inside of Instance.Destroying connection inside of a script that is bound to be destroyed is killed prematurely

Hi,

So in order to handle cleaning up a tool when the tool is about to be destroyed, I rely on an Instance.Destroying event. The issue is that because I want to wait a certain amount of time before destroying certain instances (outside of the tool, IKControls to be specific), I believe the thread gets killed because it’s put into a suspended state (threads can only be killed via coroutine.close/task.cancel when the threads are in a yielding/suspended state)

Does anyone know how I can work around this? For reference it’s a module script inside of the tool that is about to be destroyed.

I’ve tried task.delay, task.spawn, and coroutine.wrap all to no avail. I’ve tried tweening the IKControl’s weight to 0, then doing a task.delay/spawn/coroutine.wrap to get rid of the neckIKControl after the tween’s duration but again this didn’t work because of the thread’s suspended state.

	tool.Destroying:Connect(function()
		cleanUnequipped(true) --> cleans up when the tool is unequipped, pass true to not tween the ikControl weights to 0

		if descendantConnection then
			descendantConnection:Disconnect()
		end

		neckIKControl.SmoothTime = 0.25
		armIKControl.SmoothTime = 0.25
		
		neckIKControl.Weight = 0
		armIKControl.Weight = 0
		
		coroutine.wrap(function() -- relevant part
			print('a') --> prints
			
			task.wait(0.5)
			
			print('b') --> does not print, guessing the thread died
			
			neckIKControl:Destroy() --> does not get destroyed
			armIKControl:Destroy() --> also does not get destroyed
		end)()
		
		weld:Destroy()
	end)

Any ideas?

1 Like

has a similar problem but couldnt find a solution but what i did is clone a script inside the actual script to workspace then make it enabled

old school way anyway was to just slap in another script inside other instances and enable it, have it wait the 0.5 seconds inside that script, and then do the destroying itself (script.Parent:Destroy())

That seems awfully hacky. Is there not a way to just spawn the threads and not have them be killable until they naturally reach the end of their like “lifetime” for lack of a better word? (cc @a19_9)

Try task.defer. It resumes the thread after the resumption cycle, meaning it will not be running to be killed by the engine.

task.defer(function()
	task.wait(0.5)
	
	print("hey")
end)

PS: Try defining your functions before passing them as parameters for events and other functions, because they might not cache and will waste memory.

2 Likes

Good idea, hadn’t thought of that. Thanks!

oh its definitely hacky but it worked lmao

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.