zunda
(zunda)
1
If Task.sleep() is too long, it will fail.
- Widnows 10
- Docker
- Swift
- Swift version 5.5.1 (swift-5.5.1-RELEASE)
- Target: x86_64-unknown-linux-gnu
Fail
Task {
print("Start")
do {
try await Task.sleep(nanoseconds: 1_000_000_000)
}
catch {
print("Error")
}
print("Finish")
}
// output
root@80270fb670dc:/usr/src# swift testSleep.swift
Start
root@80270fb670dc:/usr/src#
Success
Task {
print("Start")
do {
try await Task.sleep(nanoseconds: 1_000)
}
catch {
print("Error")
}
print("Finish")
}
// output
root@80270fb670dc:/usr/src# swift testSleep.swift
Start
Finish
root@80270fb670dc:/usr/src#
lukasa
(Cory Benfield)
2
Is anything awaiting the completion of this task?
1 Like
zunda
(zunda)
3
nothing.
all code is posted code.
Nothing is waiting for that task to complete before finishing the program execution.
When creating a task with the Task.init or Task.detached the program doesn't magically wait for them to finish.
I recommend you to use a @main struct with an async run to get a proper async context on a CLI app.
// rename your file other than main.swift
@main
struct App {
static func main() async throws {
print("Start")
do {
try await Task.sleep(nanoseconds: 1_000_000_000)
}
catch {
print("Error")
}
print("Finish")
}
}
Output:
Start
Finish
Program ended with exit code: 0
4 Likes
zunda
(zunda)
5
can it run with swift main.swift?
I tried then error has occured.
Can I run main.swift without compile?
root@80270fb670dc:/usr/src# swift run main.swift
warning: 'swift run file.swift' command to interpret swift files is deprecated; use 'swift file.swift' instead
main.swift:1:1: error: 'main' attribute cannot be used in a module that contains top-level code
@main
^
main.swift:1:1: note: top-level code defined in this source file
@main
^
root@80270fb670dc:/usr/src#
xwu
(Xiaodi Wu)
6
As the diagnostics tell you:
It is not allowed to designate a main entry point with @main while also having top-level code (which is a main entry point), since those would be mutually contradictory as to which is the actual main entry point. Further, any module that contains a file named main.swift is considered to have top-level code. Please direct your attention to @Alejandro_Martinez's comment:
zunda
(zunda)
7
@Alejandro_Martinez
Sorry I made a mistake in reading.
change file name to "testSleep.swift"
root@80270fb670dc:/usr/src# swift testSleep.swift
testSleep.swift:1:1: error: 'main' attribute cannot be used in a module that contains top-level code
@main
^
testSleep.swift:1:1: note: top-level code defined in this source file
@main
^
root@80270fb670dc:/usr/src#
xwu
(Xiaodi Wu)
8
The diagnostic tells you exactly what's not right: you still have top-level code.
zunda
(zunda)
9
if I delete @main, swift testSleep.swift shows nothing.
// testSleep.swift
@main
struct App {
static func main() async throws {
print("Start")
do {
try await Task.sleep(nanoseconds: 1_000_000_000)
}
catch {
print("Error")
}
print("Finish")
}
}
xwu
(Xiaodi Wu)
10
Ah, I understand your question. You don't have any other code except what you're showing, and you're literally running swift testSleep.swift. Unfortunately, that is just not supported.
You'll need to create a new Swift package (swift package init --type executable) and put your code in the package (and not in a file named main.swift!). Then you can just invoke swift run and it will run your code. (On macOS, you will also need to set the supported platform by adding platforms: [.macOS(.v10_15)] to Package.swift.)
2 Likes
Jon_Shier
(Jon Shier)
11
Or just run swiftc taskSleep.swift and then the resulting executable ./taskSleep.
2 Likes
zunda
(zunda)
12
Thanks for answering.
I found another method.
But Maybe this is not best.
Process doesn't finish when it shows "Finish".
Task {
print("Start")
do {
try await Task.sleep(nanoseconds: 1_000_000_000)
}
catch {
print("Error")
}
print("Finish")
}
RunLoop.main.run() // <-Add
swift testSleep.swift
Jon_Shier
(Jon Shier)
13
You've already been given a working example. Use the @main version that was posted above. Put it in a file not named main.swift. (I'll assume testSleep.swift.) Compile it using swiftc testSleep.swift. Run it using ./testSleep.
1 Like
zunda
(zunda)
14
Thanks!
using compile result is perfect.
I want method without compile.
But swift/swiftc doesnt support running async code without compile.