Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

How do you wait for a thread to be done ?

Asked by
Cirillix 110
2 years ago

Basically I want "Loaded" to be set to true when all of the threads have been ran AND finished (aka the spawn function you can see there). How would I go about doing that efficiently ?

while true do
    for i,v in ipairs(DataStorePages:GetCurrentPage()) do
        spawn(function()
            local BlockData
                local success2, errorMessage2
            success2, errorMessage2 = pcall(function()
                BlockData = BlocksDatastore:GetAsync(v.key)
            end)
            if success2 then
                LoadBlock(BlockData)
            else
                table.insert(FailedDataCache, v.key)
            end
        end)    
    end

    if DataStorePages.IsFinished == false then
        DataStorePages:AdvanceToNextPageAsync()
    else    
        break
    end
end

    Loaded.Value = true

1 answer

Log in to vote
1
Answered by
imKirda 4491 Moderation Voter Community Moderator
2 years ago

You can create counter, every time you spawn something, increase the counter by 1, at the end of the function, decrease the counter back by 1, this means counter won't be 0 while at least single thread is active, then you can repeatedly wait until counter ain't 0:

local count = 0

while true do
    for i,v in ipairs(DataStorePages:GetCurrentPage()) do
        spawn(function()
            count += 1

            local BlockData
                local success2, errorMessage2
            success2, errorMessage2 = pcall(function()
                BlockData = BlocksDatastore:GetAsync(v.key)
            end)
            if success2 then
                LoadBlock(BlockData)
            else
                table.insert(FailedDataCache, v.key)
            end

            count -= 1
        end)    
    end

    if DataStorePages.IsFinished == false then
        DataStorePages:AdvanceToNextPageAsync()
    else    
        break
    end
end

while count ~= 0 do
    task.wait()
end

Loaded.Value = true

However if i leave the while not something do task.wait() end is non-professional, the code won't just wait once, it will repeatedly wait every frame, of course you won't see performance difference but who cares, other simple way better than this is by using BindableEvent:

local finished = Instance.new("BindableEvent")
local count = 0

while true do
    for i,v in ipairs(DataStorePages:GetCurrentPage()) do
        spawn(function()
            count += 1

            local BlockData
                local success2, errorMessage2
            success2, errorMessage2 = pcall(function()
                BlockData = BlocksDatastore:GetAsync(v.key)
            end)
            if success2 then
                LoadBlock(BlockData)
            else
                table.insert(FailedDataCache, v.key)
            end

            count -= 1
            finished.Event:Fire()
        end)    
    end

    if DataStorePages.IsFinished == false then
        DataStorePages:AdvanceToNextPageAsync()
    else    
        break
    end
end

while count ~= 0 do
    finished.Event:Wait()
end

Loaded.Value = true

That way it will only check if count isn't 0 every time finished is fired, that is every time spawn thread ends since i added the :Fire there. :Wait is a function that waits until :Fire is executed.

Ad

Answer this question