How to kill a coroutine.wrap?

I have a coroutine.wrap with an infinite loop (waiting screen):

coroutine.wrap(function() 
	while true do
		for Num = 0, 3 do
			TextLabel.Text = 'Wait' .. string.rep('.', Num)
			wait(0.5)
		end
	end
end)()

At some point, I need to stop this coroutine.
Is there any simple command to kill this coroutine.wrap?

No, but you can just add a variable outside the coroutine and then change it to false after.

Like this for example:

local isRunning = true

coroutine.wrap(function() 
	while isRunning do
		for Num = 0, 3 do
			TextLabel.Text = 'Wait' .. string.rep('.', Num)

			task.wait(0.5)
		end
	end
end)()

--//Stops coroutine
task.wait(3)
isRunning = false

Edit: Don’t do what I did above, this is an easier and more performant solution using threads:

local thread = task.spawn(function()
	while true do
		for Num = 0, 3 do
			TextLabel.Text = 'Wait' .. string.rep('.', Num)

			task.wait(0.5)
		end
	end
end)()

-- Stops thread
task.wait(3)
task.cancel(thread)
4 Likes

Use the condition of the while loop.

local Killed = false

coroutine.wrap(function() 
	while not Killed do
		for Num = 0, 3 do
			TextLabel.Text = 'Wait' .. string.rep('.', Num)
			wait(0.5)
		end

        Killed = true
	end
end)()
1 Like

New task.cancel and coroutine.close functions have been added. The returned thread can be closed from that. But coroutine.wrap returns a function, not a thread. So you’ll have to use coroutine.create or task.spawn instead.

local thread = task.spawn(function() ... end)
-- To stop it:
task.cancel(thread)

But that should only be used when you need to kill the thread right away, which, depending on your yielding strategies inside the thread, might not be great. I would recommend doing what the people above me have posted, in terms of using some control flag for the loop’s condition.

10 Likes

See updated code snippet below.

Error:

Workspace.Script:6: Workspace.Script:3: cannot close running coroutine

local routine = coroutine.wrap(function()
	return coroutine.running()
end)

local thread = routine()
coroutine.close(thread)
print(coroutine.status(thread)) --'dead'
1 Like

Could you show me how to embed the loop in OP?
In a way that I can start and stop it?

If I try this:

local routine = coroutine.wrap(function()
	while true do
		for Num = 0, 3 do
			print('Wait' .. string.rep('.', Num))
			wait(0.5)
		end
	end
end)

local thread = routine()
wait(5)
coroutine.close(thread)

I get:

Wait
Wait.
Wait…
Wait…
Wait
Wait.
Wait…
Wait…
Wait
Wait.
Workspace.Script:12: invalid argument #1 to ‘close’ (thread expected, got nil)
Stack Begin
Script ‘Workspace.Script’, Line 12
Stack End

It seams thread is becoming nil

That’s because your coroutine’s function isn’t returning anything.

local Routine = {}

function Routine.new()
	return coroutine.wrap(function(arg)
		if arg then coroutine.yield(coroutine.running()) end
		while true do
			print("Hello world!")
			task.wait(1)
		end
	end)
end

local routine = Routine.new() --Create new coroutine function.
local thread = routine(true) --Retrive the coroutine function's thread.
routine() --Run the coroutine function's loop.
task.wait(3)
coroutine.close(thread) --Close the coroutine function's thread.

task.wait(3) --Intermission.

routine = Routine.new() ---Create another coroutine function and repeat the process.
thread = routine(true)
routine()
task.wait(3)
coroutine.close(thread)
1 Like

Thanks, but this is getting more complex than it should be.
Doing a simple replacement of your while with the content of my while

local Routine = {}

function Routine.new()
	return coroutine.wrap(function(arg)
		if arg then coroutine.yield(coroutine.running()) end
		
		while true do
			for Num = 0, 3 do
				print('Wait' .. string.rep('.', Num))
				wait(0.5)
			end
		end
		
	end)
end

local routine = Routine.new() --Create new coroutine function.
local thread = routine(true) --Retrive the coroutine function's thread.
routine() --Run the coroutine function's loop.
task.wait(5)
coroutine.close(thread) --Close the coroutine function's thread.
print('ok--------')

… now comes this error:

cannot resume dead coroutine

1 Like
local v = false

local function f()
	while true do
		for Num = 0, 3 do
			if v then coroutine.yield() end
			print('Wait' .. string.rep('.', Num))
			wait(0.5)
		end
	end
end

local t = coroutine.create(f) --Create task.
coroutine.resume(t) --Resume task.
task.wait(2) --Wait 2 seconds.
v = true --Toggle state variable on causing task to yield.
task.wait(2) --Wait 2 seconds.
v = false --Toggle state variable off.
coroutine.resume(t) --Resume task.
task.wait(2) --Wait 2 seconds.
v = true --Toggle state variable on causing task to yield.
1 Like

this approach is basically called ‘semaphores’, i suppose

1 Like

…This… was… TWO years ago… ???