Swift Async print order?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
7
down vote

favorite
7












Does this always print in the order of 1 5 2 4 3?



print("1")
DispatchQueue.main.async
print("2")
DispatchQueue.main.async
print(3)

print("4")

print("5")


I feel the answer is no, but I cannot explain it and hope someone could clarify my understanding. Thank you!










share|improve this question



















  • 1




    Yes, it is obvious for 1 ,5 after that it switches to main queue prints 2, Then you again request main queue task but it will not wait for it and prints 4 and then 3
    – Prashant Tukadiya
    1 hour ago







  • 3




    You need to clarify one thing, whether print("1") is executed in the main thread or not.
    – OOPer
    1 hour ago






  • 1




    why would it matter? It would always execute first.
    – Unikorn
    1 hour ago










  • I suspect is due to the execution order: print("1") // 1. executes prints 1 DispatchQueue.main.async // 2. switches to main thread print("2") // 4. executes print 3 DispatchQueue.main.async // 5. switches to main thread print(3) // 7. executes print 3 print("4") // 6. executes print 4 print("5") // 3. executes print 5
    – Unikorn
    44 mins ago










  • @OOPer, please forgive my ignorant for my earlier remark thinking it will always execute first.
    – Unikorn
    12 mins ago














up vote
7
down vote

favorite
7












Does this always print in the order of 1 5 2 4 3?



print("1")
DispatchQueue.main.async
print("2")
DispatchQueue.main.async
print(3)

print("4")

print("5")


I feel the answer is no, but I cannot explain it and hope someone could clarify my understanding. Thank you!










share|improve this question



















  • 1




    Yes, it is obvious for 1 ,5 after that it switches to main queue prints 2, Then you again request main queue task but it will not wait for it and prints 4 and then 3
    – Prashant Tukadiya
    1 hour ago







  • 3




    You need to clarify one thing, whether print("1") is executed in the main thread or not.
    – OOPer
    1 hour ago






  • 1




    why would it matter? It would always execute first.
    – Unikorn
    1 hour ago










  • I suspect is due to the execution order: print("1") // 1. executes prints 1 DispatchQueue.main.async // 2. switches to main thread print("2") // 4. executes print 3 DispatchQueue.main.async // 5. switches to main thread print(3) // 7. executes print 3 print("4") // 6. executes print 4 print("5") // 3. executes print 5
    – Unikorn
    44 mins ago










  • @OOPer, please forgive my ignorant for my earlier remark thinking it will always execute first.
    – Unikorn
    12 mins ago












up vote
7
down vote

favorite
7









up vote
7
down vote

favorite
7






7





Does this always print in the order of 1 5 2 4 3?



print("1")
DispatchQueue.main.async
print("2")
DispatchQueue.main.async
print(3)

print("4")

print("5")


I feel the answer is no, but I cannot explain it and hope someone could clarify my understanding. Thank you!










share|improve this question















Does this always print in the order of 1 5 2 4 3?



print("1")
DispatchQueue.main.async
print("2")
DispatchQueue.main.async
print(3)

print("4")

print("5")


I feel the answer is no, but I cannot explain it and hope someone could clarify my understanding. Thank you!







swift asynchronous grand-central-dispatch dispatch-async






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 1 hour ago

























asked 1 hour ago









Unikorn

4301817




4301817







  • 1




    Yes, it is obvious for 1 ,5 after that it switches to main queue prints 2, Then you again request main queue task but it will not wait for it and prints 4 and then 3
    – Prashant Tukadiya
    1 hour ago







  • 3




    You need to clarify one thing, whether print("1") is executed in the main thread or not.
    – OOPer
    1 hour ago






  • 1




    why would it matter? It would always execute first.
    – Unikorn
    1 hour ago










  • I suspect is due to the execution order: print("1") // 1. executes prints 1 DispatchQueue.main.async // 2. switches to main thread print("2") // 4. executes print 3 DispatchQueue.main.async // 5. switches to main thread print(3) // 7. executes print 3 print("4") // 6. executes print 4 print("5") // 3. executes print 5
    – Unikorn
    44 mins ago










  • @OOPer, please forgive my ignorant for my earlier remark thinking it will always execute first.
    – Unikorn
    12 mins ago












  • 1




    Yes, it is obvious for 1 ,5 after that it switches to main queue prints 2, Then you again request main queue task but it will not wait for it and prints 4 and then 3
    – Prashant Tukadiya
    1 hour ago







  • 3




    You need to clarify one thing, whether print("1") is executed in the main thread or not.
    – OOPer
    1 hour ago






  • 1




    why would it matter? It would always execute first.
    – Unikorn
    1 hour ago










  • I suspect is due to the execution order: print("1") // 1. executes prints 1 DispatchQueue.main.async // 2. switches to main thread print("2") // 4. executes print 3 DispatchQueue.main.async // 5. switches to main thread print(3) // 7. executes print 3 print("4") // 6. executes print 4 print("5") // 3. executes print 5
    – Unikorn
    44 mins ago










  • @OOPer, please forgive my ignorant for my earlier remark thinking it will always execute first.
    – Unikorn
    12 mins ago







1




1




Yes, it is obvious for 1 ,5 after that it switches to main queue prints 2, Then you again request main queue task but it will not wait for it and prints 4 and then 3
– Prashant Tukadiya
1 hour ago





Yes, it is obvious for 1 ,5 after that it switches to main queue prints 2, Then you again request main queue task but it will not wait for it and prints 4 and then 3
– Prashant Tukadiya
1 hour ago





3




3




You need to clarify one thing, whether print("1") is executed in the main thread or not.
– OOPer
1 hour ago




You need to clarify one thing, whether print("1") is executed in the main thread or not.
– OOPer
1 hour ago




1




1




why would it matter? It would always execute first.
– Unikorn
1 hour ago




why would it matter? It would always execute first.
– Unikorn
1 hour ago












I suspect is due to the execution order: print("1") // 1. executes prints 1 DispatchQueue.main.async // 2. switches to main thread print("2") // 4. executes print 3 DispatchQueue.main.async // 5. switches to main thread print(3) // 7. executes print 3 print("4") // 6. executes print 4 print("5") // 3. executes print 5
– Unikorn
44 mins ago




I suspect is due to the execution order: print("1") // 1. executes prints 1 DispatchQueue.main.async // 2. switches to main thread print("2") // 4. executes print 3 DispatchQueue.main.async // 5. switches to main thread print(3) // 7. executes print 3 print("4") // 6. executes print 4 print("5") // 3. executes print 5
– Unikorn
44 mins ago












@OOPer, please forgive my ignorant for my earlier remark thinking it will always execute first.
– Unikorn
12 mins ago




@OOPer, please forgive my ignorant for my earlier remark thinking it will always execute first.
– Unikorn
12 mins ago












2 Answers
2






active

oldest

votes

















up vote
6
down vote













It depends on which thread you start the operation.



If you start from the main then, then you get 1, 5, 2, 4, 3



If you start from a background thread, then most of the time you'll get them same result (1, 5, 2, 4, 3), however this is not guaranteed as the background thread can be put to sleep at any time by the OS, and if this happens right before the print(5)call, then 5 will be the last to be printed.



Just a note that if the code from the question is the only one in your app/playground, then you might be surprised by running into partial prints, as the app/playground exits as soon as it hits the print(5) line, before having a chance to execute the async dispatch. To circumvent this, you can make sure that RunLoop.current.run() gets executed on the main thread as the last part of your code.



Here are some diagram that try to illustrate what happens in the main-thread-only scenario, and the one where a background thread is involved:



enter image description hereenter image description here






share|improve this answer


















  • 2




    You get a +1 for the nice pictures.
    – rmaddy
    24 mins ago










  • Yeah, +1 for pictures. Thanks!
    – Unikorn
    9 mins ago

















up vote
6
down vote













You will always get 1, 2, 4, 3. The 5 will always be after the 1. But where it ends up in relation to the others depends on what queue the whole thing started on.



If this is started from the main queue then 5 will always be between 1 and 2.



Here's why:



This code starts on the main queue. 1 is printed. You then enqueue another block to run asynchronously on the main queue so that block will be run after the current block completes and the main queue gets to the end of the current run loop. The code continues to the next line which is to print 5. The current block ends and the next block on the main queue is run. This is the block of the first call to DispatchQueue.main.async. As this block runs it prints 2 (so now we have 1 5 2). Another block is enqueued to the main queue just like the last one. The current block continues and prints 4 (so now we have 1 5 2 4). The block ends and the next block on the main queue is run. This is the final block we added. That block runs and it prints 3 giving the final output of 1 5 2 4 3.



If you started on some background queue then 5 can appear anywhere after 1 but for such simple code, the 5 will most likely still appear between 1 and 2 but it can appear anywhere after the 1 in a general case.



Here's why:



This code starts on a background queue. 1 is printed. You then enqueue another block to run asynchronously on the main queue so that block will be run after the current main queue run loop completes. The code continues to the next line which is to print 5. The current block ends. The block added to the main queue is run in parallel to the background queue. Depending on the time of when the block added to the main queue is run in relation to the remaining code on the background queue is run, the output of print("5") can be intermingled with the prints from the main queue. This is why the 5 can appear anywhere after the 1 when started from the background.



But the simple code in the question will likely always give 1 5 2 4 3 even when started on the background because the code is so short and takes so little time.



Here's some code that puts the 5 elsewhere:



func asyncTest() 
print("1")
DispatchQueue.main.async
print("2")
DispatchQueue.main.async
print(3)

print("4")


for _ in 0...1000


print("5")


DispatchQueue.global(qos: .background).async
asyncTest()



The existence of the loop causes the 5 to take a little longer before it appears which allows the main queue to get executed some before 5 is printed. Without the loop, the background thread executes too quickly so the 5 appears before 2.



If running this test in a playground, add:



PlaygroundPage.current.needsIndefiniteExecution = true


to the top of the playground (just after the imports). You will also need:



import PlaygroundSupport





share|improve this answer






















  • I ran this in playground 10+ times and always get : 1 5 2 4 3
    – Unikorn
    1 hour ago










  • Most likely you are starting this on the main queue so that will always give you that result, just as I stated in my answer.
    – rmaddy
    1 hour ago






  • 1




    Can you give an example of a code that could print it in another order?
    – Sweeper
    1 hour ago










  • @Sweeper Any code that results in this code being started on any background queue could result in the 5 being elsewhere.
    – rmaddy
    1 hour ago






  • 1




    Please feel free to comment if you down vote and explain why you think this answer is incorrect. I don't bite. Thanks.
    – rmaddy
    54 mins ago










Your Answer





StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52733121%2fswift-async-print-order%23new-answer', 'question_page');

);

Post as a guest






























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
6
down vote













It depends on which thread you start the operation.



If you start from the main then, then you get 1, 5, 2, 4, 3



If you start from a background thread, then most of the time you'll get them same result (1, 5, 2, 4, 3), however this is not guaranteed as the background thread can be put to sleep at any time by the OS, and if this happens right before the print(5)call, then 5 will be the last to be printed.



Just a note that if the code from the question is the only one in your app/playground, then you might be surprised by running into partial prints, as the app/playground exits as soon as it hits the print(5) line, before having a chance to execute the async dispatch. To circumvent this, you can make sure that RunLoop.current.run() gets executed on the main thread as the last part of your code.



Here are some diagram that try to illustrate what happens in the main-thread-only scenario, and the one where a background thread is involved:



enter image description hereenter image description here






share|improve this answer


















  • 2




    You get a +1 for the nice pictures.
    – rmaddy
    24 mins ago










  • Yeah, +1 for pictures. Thanks!
    – Unikorn
    9 mins ago














up vote
6
down vote













It depends on which thread you start the operation.



If you start from the main then, then you get 1, 5, 2, 4, 3



If you start from a background thread, then most of the time you'll get them same result (1, 5, 2, 4, 3), however this is not guaranteed as the background thread can be put to sleep at any time by the OS, and if this happens right before the print(5)call, then 5 will be the last to be printed.



Just a note that if the code from the question is the only one in your app/playground, then you might be surprised by running into partial prints, as the app/playground exits as soon as it hits the print(5) line, before having a chance to execute the async dispatch. To circumvent this, you can make sure that RunLoop.current.run() gets executed on the main thread as the last part of your code.



Here are some diagram that try to illustrate what happens in the main-thread-only scenario, and the one where a background thread is involved:



enter image description hereenter image description here






share|improve this answer


















  • 2




    You get a +1 for the nice pictures.
    – rmaddy
    24 mins ago










  • Yeah, +1 for pictures. Thanks!
    – Unikorn
    9 mins ago












up vote
6
down vote










up vote
6
down vote









It depends on which thread you start the operation.



If you start from the main then, then you get 1, 5, 2, 4, 3



If you start from a background thread, then most of the time you'll get them same result (1, 5, 2, 4, 3), however this is not guaranteed as the background thread can be put to sleep at any time by the OS, and if this happens right before the print(5)call, then 5 will be the last to be printed.



Just a note that if the code from the question is the only one in your app/playground, then you might be surprised by running into partial prints, as the app/playground exits as soon as it hits the print(5) line, before having a chance to execute the async dispatch. To circumvent this, you can make sure that RunLoop.current.run() gets executed on the main thread as the last part of your code.



Here are some diagram that try to illustrate what happens in the main-thread-only scenario, and the one where a background thread is involved:



enter image description hereenter image description here






share|improve this answer














It depends on which thread you start the operation.



If you start from the main then, then you get 1, 5, 2, 4, 3



If you start from a background thread, then most of the time you'll get them same result (1, 5, 2, 4, 3), however this is not guaranteed as the background thread can be put to sleep at any time by the OS, and if this happens right before the print(5)call, then 5 will be the last to be printed.



Just a note that if the code from the question is the only one in your app/playground, then you might be surprised by running into partial prints, as the app/playground exits as soon as it hits the print(5) line, before having a chance to execute the async dispatch. To circumvent this, you can make sure that RunLoop.current.run() gets executed on the main thread as the last part of your code.



Here are some diagram that try to illustrate what happens in the main-thread-only scenario, and the one where a background thread is involved:



enter image description hereenter image description here







share|improve this answer














share|improve this answer



share|improve this answer








edited 26 mins ago

























answered 39 mins ago









Cristik

16.6k114174




16.6k114174







  • 2




    You get a +1 for the nice pictures.
    – rmaddy
    24 mins ago










  • Yeah, +1 for pictures. Thanks!
    – Unikorn
    9 mins ago












  • 2




    You get a +1 for the nice pictures.
    – rmaddy
    24 mins ago










  • Yeah, +1 for pictures. Thanks!
    – Unikorn
    9 mins ago







2




2




You get a +1 for the nice pictures.
– rmaddy
24 mins ago




You get a +1 for the nice pictures.
– rmaddy
24 mins ago












Yeah, +1 for pictures. Thanks!
– Unikorn
9 mins ago




Yeah, +1 for pictures. Thanks!
– Unikorn
9 mins ago












up vote
6
down vote













You will always get 1, 2, 4, 3. The 5 will always be after the 1. But where it ends up in relation to the others depends on what queue the whole thing started on.



If this is started from the main queue then 5 will always be between 1 and 2.



Here's why:



This code starts on the main queue. 1 is printed. You then enqueue another block to run asynchronously on the main queue so that block will be run after the current block completes and the main queue gets to the end of the current run loop. The code continues to the next line which is to print 5. The current block ends and the next block on the main queue is run. This is the block of the first call to DispatchQueue.main.async. As this block runs it prints 2 (so now we have 1 5 2). Another block is enqueued to the main queue just like the last one. The current block continues and prints 4 (so now we have 1 5 2 4). The block ends and the next block on the main queue is run. This is the final block we added. That block runs and it prints 3 giving the final output of 1 5 2 4 3.



If you started on some background queue then 5 can appear anywhere after 1 but for such simple code, the 5 will most likely still appear between 1 and 2 but it can appear anywhere after the 1 in a general case.



Here's why:



This code starts on a background queue. 1 is printed. You then enqueue another block to run asynchronously on the main queue so that block will be run after the current main queue run loop completes. The code continues to the next line which is to print 5. The current block ends. The block added to the main queue is run in parallel to the background queue. Depending on the time of when the block added to the main queue is run in relation to the remaining code on the background queue is run, the output of print("5") can be intermingled with the prints from the main queue. This is why the 5 can appear anywhere after the 1 when started from the background.



But the simple code in the question will likely always give 1 5 2 4 3 even when started on the background because the code is so short and takes so little time.



Here's some code that puts the 5 elsewhere:



func asyncTest() 
print("1")
DispatchQueue.main.async
print("2")
DispatchQueue.main.async
print(3)

print("4")


for _ in 0...1000


print("5")


DispatchQueue.global(qos: .background).async
asyncTest()



The existence of the loop causes the 5 to take a little longer before it appears which allows the main queue to get executed some before 5 is printed. Without the loop, the background thread executes too quickly so the 5 appears before 2.



If running this test in a playground, add:



PlaygroundPage.current.needsIndefiniteExecution = true


to the top of the playground (just after the imports). You will also need:



import PlaygroundSupport





share|improve this answer






















  • I ran this in playground 10+ times and always get : 1 5 2 4 3
    – Unikorn
    1 hour ago










  • Most likely you are starting this on the main queue so that will always give you that result, just as I stated in my answer.
    – rmaddy
    1 hour ago






  • 1




    Can you give an example of a code that could print it in another order?
    – Sweeper
    1 hour ago










  • @Sweeper Any code that results in this code being started on any background queue could result in the 5 being elsewhere.
    – rmaddy
    1 hour ago






  • 1




    Please feel free to comment if you down vote and explain why you think this answer is incorrect. I don't bite. Thanks.
    – rmaddy
    54 mins ago














up vote
6
down vote













You will always get 1, 2, 4, 3. The 5 will always be after the 1. But where it ends up in relation to the others depends on what queue the whole thing started on.



If this is started from the main queue then 5 will always be between 1 and 2.



Here's why:



This code starts on the main queue. 1 is printed. You then enqueue another block to run asynchronously on the main queue so that block will be run after the current block completes and the main queue gets to the end of the current run loop. The code continues to the next line which is to print 5. The current block ends and the next block on the main queue is run. This is the block of the first call to DispatchQueue.main.async. As this block runs it prints 2 (so now we have 1 5 2). Another block is enqueued to the main queue just like the last one. The current block continues and prints 4 (so now we have 1 5 2 4). The block ends and the next block on the main queue is run. This is the final block we added. That block runs and it prints 3 giving the final output of 1 5 2 4 3.



If you started on some background queue then 5 can appear anywhere after 1 but for such simple code, the 5 will most likely still appear between 1 and 2 but it can appear anywhere after the 1 in a general case.



Here's why:



This code starts on a background queue. 1 is printed. You then enqueue another block to run asynchronously on the main queue so that block will be run after the current main queue run loop completes. The code continues to the next line which is to print 5. The current block ends. The block added to the main queue is run in parallel to the background queue. Depending on the time of when the block added to the main queue is run in relation to the remaining code on the background queue is run, the output of print("5") can be intermingled with the prints from the main queue. This is why the 5 can appear anywhere after the 1 when started from the background.



But the simple code in the question will likely always give 1 5 2 4 3 even when started on the background because the code is so short and takes so little time.



Here's some code that puts the 5 elsewhere:



func asyncTest() 
print("1")
DispatchQueue.main.async
print("2")
DispatchQueue.main.async
print(3)

print("4")


for _ in 0...1000


print("5")


DispatchQueue.global(qos: .background).async
asyncTest()



The existence of the loop causes the 5 to take a little longer before it appears which allows the main queue to get executed some before 5 is printed. Without the loop, the background thread executes too quickly so the 5 appears before 2.



If running this test in a playground, add:



PlaygroundPage.current.needsIndefiniteExecution = true


to the top of the playground (just after the imports). You will also need:



import PlaygroundSupport





share|improve this answer






















  • I ran this in playground 10+ times and always get : 1 5 2 4 3
    – Unikorn
    1 hour ago










  • Most likely you are starting this on the main queue so that will always give you that result, just as I stated in my answer.
    – rmaddy
    1 hour ago






  • 1




    Can you give an example of a code that could print it in another order?
    – Sweeper
    1 hour ago










  • @Sweeper Any code that results in this code being started on any background queue could result in the 5 being elsewhere.
    – rmaddy
    1 hour ago






  • 1




    Please feel free to comment if you down vote and explain why you think this answer is incorrect. I don't bite. Thanks.
    – rmaddy
    54 mins ago












up vote
6
down vote










up vote
6
down vote









You will always get 1, 2, 4, 3. The 5 will always be after the 1. But where it ends up in relation to the others depends on what queue the whole thing started on.



If this is started from the main queue then 5 will always be between 1 and 2.



Here's why:



This code starts on the main queue. 1 is printed. You then enqueue another block to run asynchronously on the main queue so that block will be run after the current block completes and the main queue gets to the end of the current run loop. The code continues to the next line which is to print 5. The current block ends and the next block on the main queue is run. This is the block of the first call to DispatchQueue.main.async. As this block runs it prints 2 (so now we have 1 5 2). Another block is enqueued to the main queue just like the last one. The current block continues and prints 4 (so now we have 1 5 2 4). The block ends and the next block on the main queue is run. This is the final block we added. That block runs and it prints 3 giving the final output of 1 5 2 4 3.



If you started on some background queue then 5 can appear anywhere after 1 but for such simple code, the 5 will most likely still appear between 1 and 2 but it can appear anywhere after the 1 in a general case.



Here's why:



This code starts on a background queue. 1 is printed. You then enqueue another block to run asynchronously on the main queue so that block will be run after the current main queue run loop completes. The code continues to the next line which is to print 5. The current block ends. The block added to the main queue is run in parallel to the background queue. Depending on the time of when the block added to the main queue is run in relation to the remaining code on the background queue is run, the output of print("5") can be intermingled with the prints from the main queue. This is why the 5 can appear anywhere after the 1 when started from the background.



But the simple code in the question will likely always give 1 5 2 4 3 even when started on the background because the code is so short and takes so little time.



Here's some code that puts the 5 elsewhere:



func asyncTest() 
print("1")
DispatchQueue.main.async
print("2")
DispatchQueue.main.async
print(3)

print("4")


for _ in 0...1000


print("5")


DispatchQueue.global(qos: .background).async
asyncTest()



The existence of the loop causes the 5 to take a little longer before it appears which allows the main queue to get executed some before 5 is printed. Without the loop, the background thread executes too quickly so the 5 appears before 2.



If running this test in a playground, add:



PlaygroundPage.current.needsIndefiniteExecution = true


to the top of the playground (just after the imports). You will also need:



import PlaygroundSupport





share|improve this answer














You will always get 1, 2, 4, 3. The 5 will always be after the 1. But where it ends up in relation to the others depends on what queue the whole thing started on.



If this is started from the main queue then 5 will always be between 1 and 2.



Here's why:



This code starts on the main queue. 1 is printed. You then enqueue another block to run asynchronously on the main queue so that block will be run after the current block completes and the main queue gets to the end of the current run loop. The code continues to the next line which is to print 5. The current block ends and the next block on the main queue is run. This is the block of the first call to DispatchQueue.main.async. As this block runs it prints 2 (so now we have 1 5 2). Another block is enqueued to the main queue just like the last one. The current block continues and prints 4 (so now we have 1 5 2 4). The block ends and the next block on the main queue is run. This is the final block we added. That block runs and it prints 3 giving the final output of 1 5 2 4 3.



If you started on some background queue then 5 can appear anywhere after 1 but for such simple code, the 5 will most likely still appear between 1 and 2 but it can appear anywhere after the 1 in a general case.



Here's why:



This code starts on a background queue. 1 is printed. You then enqueue another block to run asynchronously on the main queue so that block will be run after the current main queue run loop completes. The code continues to the next line which is to print 5. The current block ends. The block added to the main queue is run in parallel to the background queue. Depending on the time of when the block added to the main queue is run in relation to the remaining code on the background queue is run, the output of print("5") can be intermingled with the prints from the main queue. This is why the 5 can appear anywhere after the 1 when started from the background.



But the simple code in the question will likely always give 1 5 2 4 3 even when started on the background because the code is so short and takes so little time.



Here's some code that puts the 5 elsewhere:



func asyncTest() 
print("1")
DispatchQueue.main.async
print("2")
DispatchQueue.main.async
print(3)

print("4")


for _ in 0...1000


print("5")


DispatchQueue.global(qos: .background).async
asyncTest()



The existence of the loop causes the 5 to take a little longer before it appears which allows the main queue to get executed some before 5 is printed. Without the loop, the background thread executes too quickly so the 5 appears before 2.



If running this test in a playground, add:



PlaygroundPage.current.needsIndefiniteExecution = true


to the top of the playground (just after the imports). You will also need:



import PlaygroundSupport






share|improve this answer














share|improve this answer



share|improve this answer








edited 25 mins ago

























answered 1 hour ago









rmaddy

231k27299366




231k27299366











  • I ran this in playground 10+ times and always get : 1 5 2 4 3
    – Unikorn
    1 hour ago










  • Most likely you are starting this on the main queue so that will always give you that result, just as I stated in my answer.
    – rmaddy
    1 hour ago






  • 1




    Can you give an example of a code that could print it in another order?
    – Sweeper
    1 hour ago










  • @Sweeper Any code that results in this code being started on any background queue could result in the 5 being elsewhere.
    – rmaddy
    1 hour ago






  • 1




    Please feel free to comment if you down vote and explain why you think this answer is incorrect. I don't bite. Thanks.
    – rmaddy
    54 mins ago
















  • I ran this in playground 10+ times and always get : 1 5 2 4 3
    – Unikorn
    1 hour ago










  • Most likely you are starting this on the main queue so that will always give you that result, just as I stated in my answer.
    – rmaddy
    1 hour ago






  • 1




    Can you give an example of a code that could print it in another order?
    – Sweeper
    1 hour ago










  • @Sweeper Any code that results in this code being started on any background queue could result in the 5 being elsewhere.
    – rmaddy
    1 hour ago






  • 1




    Please feel free to comment if you down vote and explain why you think this answer is incorrect. I don't bite. Thanks.
    – rmaddy
    54 mins ago















I ran this in playground 10+ times and always get : 1 5 2 4 3
– Unikorn
1 hour ago




I ran this in playground 10+ times and always get : 1 5 2 4 3
– Unikorn
1 hour ago












Most likely you are starting this on the main queue so that will always give you that result, just as I stated in my answer.
– rmaddy
1 hour ago




Most likely you are starting this on the main queue so that will always give you that result, just as I stated in my answer.
– rmaddy
1 hour ago




1




1




Can you give an example of a code that could print it in another order?
– Sweeper
1 hour ago




Can you give an example of a code that could print it in another order?
– Sweeper
1 hour ago












@Sweeper Any code that results in this code being started on any background queue could result in the 5 being elsewhere.
– rmaddy
1 hour ago




@Sweeper Any code that results in this code being started on any background queue could result in the 5 being elsewhere.
– rmaddy
1 hour ago




1




1




Please feel free to comment if you down vote and explain why you think this answer is incorrect. I don't bite. Thanks.
– rmaddy
54 mins ago




Please feel free to comment if you down vote and explain why you think this answer is incorrect. I don't bite. Thanks.
– rmaddy
54 mins ago

















 

draft saved


draft discarded















































 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52733121%2fswift-async-print-order%23new-answer', 'question_page');

);

Post as a guest













































































Comments

Popular posts from this blog

Long meetings (6-7 hours a day): Being “babysat” by supervisor

Is the Concept of Multiple Fantasy Races Scientifically Flawed? [closed]

Confectionery