API Delay ko - LIHACHTETAN/ClassicUO-BadNewbie-BasicIDE GitHub Wiki
Async / Await / Delay
ClassicUO โข Basic
Async Function์ ์คํฌ๋ฆฝํธ ์์ ์ ๋ง๋ญ๋๋ค. Await๋ ํด๋น ํจ์๋ฅผ ์ค๋จํ์ฌ ๊ฐ์ ์คํฌ๋ฆฝํธ์ ๋ค๋ฅธ ์ค๋น๋ ์์ ์ด ์งํ๋๋๋ก ํฉ๋๋ค. ์ ์ค๋ ๋๋ ์ ์ฒด VB.NET Task ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ ๊ณตํ๋ ๊ธฐ๋ฅ์ ์๋๋๋ค.
์ ํํ ๊ตฌ๋ฌธ
Async Function Work(ByVal value As Integer) As Task(Of Integer)
Await Delay(100)
Return value
End Function
Async Function Work() As Task
Await Delay(100)
End Function
Delay(milliseconds) -> Object (ScriptTask)
Await task
Dim value = Await task
value = Await task
Return Await task
task.IsCompleted() -> Integer (0/1)
task.IsFaulted() -> Integer (0/1)
task.IsCanceled() -> Integer (0/1)
task.Result() -> T / Unit
๋งค๊ฐ๋ณ์
millisecondsโ Delay๋ 0..2147483647 ๋ฐ๋ฆฌ์ด์ Integer๋ฅผ ๋ฐ์ต๋๋ค. 0์ ์ฆ์ ์๋ฃํ๋ฉฐ ์์, ์์์ String์ ์ก์ ์ ์๋ ์ค๋ฅ๋ฅผ ๋ ๋๋ค. ๋จ์กฐ ์๊ณ๋ก ์ต์ ๋๊ธฐ ์๊ฐ์ ์ ํ๋ฉฐ ์ ํํ ์คํ ์๊ฐ์ ๋ณด์ฅํ์ง ์์ต๋๋ค.Async Function / ByVal / Task(Of T)โ As Task๋ ๊ฐ์ด ์๊ณ As Task(Of T)๋ Basic ์ค์นผ๋ผ ๋๋ Object/Variant ๊ฒฐ๊ณผ์ ๋๋ค. ๋งค๊ฐ๋ณ์๋ ๋ช ์์ ByVal ๋๋ ParamArray๊ฐ ํ์ํ๋ฉฐ Optional๊ณผ ๋ช ๋ช ๋ ์ธ์๋ฅผ ์ง์ํฉ๋๋ค. ByRef, Async Sub/Declare๋ ๊ฑฐ๋ถํฉ๋๋ค. ์์ ์ ํ๋ก์์ ๋ณธ๋ฌธ์์ ๋ง๋ค๊ณ ์ ์ญ ํ๋๋ ๋งค๊ฐ๋ณ์ ๊ธฐ๋ณธ๊ฐ ์ด๊ธฐํ์์๋ ๋ง๋ค์ง ๋ง์ธ์.task / Awaitโ ์์ ๋ณ์๋ ํ์์ ์๋ตํ๊ฑฐ๋ As Object๋ก ์ ์ธํฉ๋๋ค. Await๋ ํ์ฌ ์คํ์ ์์ ์ ๋ ๋ฆฝ ๋ฌธ์ฅ, ๋จ์ผ ์ค์นผ๋ผ ์ ์ธ/๋์ ์ ์ ์ฒด ์ค๋ฅธ์ชฝ, Return Await๋ก ๋ฐ์ต๋๋ค. ์ฐ์ , ์กฐ๊ฑด, ํ๋/์ธ๋ฑ์ค ๋์ , Catch/Finally ๋ฐ Async Function ๋ฐ์์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ฌ๋ฌ ํจ์๊ฐ ๊ฐ์ ์์ ์ ๊ธฐ๋ค๋ฆด ์ ์์ง๋ง ์ํ ์์กด์ฑ์ ์ค๋ฅ์ ๋๋ค.IsCompleted / IsFaulted / IsCanceled / Resultโ IsCompleted๋ ์ฑ๊ณตยท์คํจยท์ทจ์ ํ 1, IsFaulted๋ ์คํจ ์ 1, IsCanceled๋ ์ทจ์ ์ 1์ ๋๋ค. ์ด Integer ์กฐ๊ฑด์ True/False์ ๋น๊ตํ ์ ์์ต๋๋ค. Result()๋ ์ ์ฅ๋ ๊ฐ์ ๋ฐํํ๊ณ ๋ฏธ์๋ฃ๋ฉด ์ค๋ฅ, ์คํจํ์ผ๋ฉด ์๋ ์ค๋ฅ๋ฅผ ๋ค์ ๋์ง๋๋ค. ์ด์ ์คํ์ ์์ ์ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ฐํ๊ฐ
์คํฌ๋ฆฝํธ์์ Async Function๊ณผ Delay๋ฅผ ํธ์ถํ๋ฉด ์ฆ์ T๊ฐ ์๋ Object (ScriptTask)๋ฅผ ๋ฐ์ต๋๋ค. Await์ Result()๋ T๋ฅผ ๋ฐํํ๋ฉฐ As Task์ Delay๋ ๊ฐ ์๋ Unit์ผ๋ก ๋๋ฉ๋๋ค. ํด๋ผ์ด์ธํธ๊ฐ Async Function์ ์ง์ ์ ์ผ๋ก ์คํํ๋ฉด ํ๋ ฅ์ ์ผ๋ก ๊ธฐ๋ค๋ ค ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ต๋๋ค. ์ซ์ ๋ฐ์ดํฐ๊ฐ ํญ์ Boolean์ธ ๊ฒ์ ์๋๋๋ค.
๋์
- ํจ์๋ ์ฒซ ๋ฒ์งธ ๋ฏธ์๋ฃ Await๊น์ง ์ฆ์ ์คํํฉ๋๋ค. ์ง์ญ ๋ณ์, ๋ฐ๋ณต ์์น, With ๊ฐ์ฒด์ ๋๋ฒ๊ฑฐ ํ๋ ์์ ์ ์ฅํ๋ค๊ฐ ์ฌ๊ฐํ ๋ ๋ณต์ํฉ๋๋ค. ์ด๋ฏธ ์๋ฃ๋ ์์ ์ ์ค๋จํ์ง ์์ผ๋ฉฐ Await ํผ์ฐ์ฐ์๋ ํ ๋ฒ๋ง ๊ณ์ฐํฉ๋๋ค.
- ์คํฌ๋ฆฝํธ ์์ ์ค๋ ๋๋ ์์ ํ ํ์ธ ์ง์ ์์ ๊ธฐํ์ ๊ฒ์ฌํ๊ณ ํ ํ์ ์ต๋ 64๊ฐ์ ์ค๋น๋ ๊ณ์ ์์ ์ ์คํํฉ๋๋ค. ์ ์ค๋ ๋๋ ์์ต๋๋ค. ๋๊ธฐ Wait๋ ์ค๋ ๊ฑธ๋ฆฌ๋ ๊ฒ์/๋ค์ดํฐ๋ธ ํธ์ถ์ ๋ค๋ฅธ ์์ ์ ์ง์ฐ์ํฌ ์ ์์ผ๋ฏ๋ก Await Delay๋ฅผ ์ฌ์ฉํ์ธ์. ๋ฏธ์๋ฃ ์์ ๋๋ ์์ง ์ฝ์ง ์์ ์คํจ ์์ ์ ์ต๋ 1024๊ฐ์ ๋๋ค.
- ์ผ์ ์ ์ง๋ ๊ณ์ ์คํ์ ๋ง์ง๋ง ์๊ฐ์ ํ๋ฆ ๋๋ค. ์ฌ๊ฐํ๋ฉด ๊ธฐํ์ด ์ง๋ ์์ ์ ์ฒ๋ฆฌํฉ๋๋ค. Stop, ์ค๋ฅ ๋๋ ์ง์ ์ ๋ฐํ์ ๋จ์ ์์ ์ ์ทจ์ํ๊ณ Using ์์๊ณผ ๋ฐ๋ณต์๋ฅผ ํด์ ํฉ๋๋ค. ๋น์ ์ทจ์๋ ์คํฌ๋ฆฝํธ Catch/Finally๋ฅผ ๊ฑด๋๋๋๋ค. ์ฝ์ง ์์ ์์ ์ค๋ฅ๋ ์ง์ ์ ์ข ๋ฃ ์ ๋ณด๊ณ ๋ฉ๋๋ค. IDE๋ง ๋ซ์์๋ ์คํ ์ค์ธ ์คํฌ๋ฆฝํธ๊ฐ ๋ฉ์ถ์ง ์์ต๋๋ค.
- Task.Run/WhenAll, ์ธ๋ถ .NET ์์ , Async Sub, Catch/Finally ๋ด Await, ์ง์ญ As Task ์ ์ธ์ ์ง์ํ์ง ์์ต๋๋ค. ํ์ํ ์์ ๋ณด๋ค Main์ด ๋จผ์ ๋๋์ง ์๊ฒ ํ์ธ์. Async/Await๋ ์์ฝ์ด์ ๋๋ค.
์์
1. ๋ ๋ฆฝ์ ์ธ ๋ ๋๊ธฐ
# ValueLater๋ value์ milliseconds๋ฅผ ๊ฐ์ผ๋ก ๋ฐ์ต๋๋ค. ๊ฒฐ๊ณผ๋ฅผ ์ฝ๊ธฐ ์ ์ ๋ ํธ์ถ์ ์์ํ์ฌ 10ms ํ 22, 30ms ํ 20์ ์ป์ต๋๋ค. Main์ ์ต๋ 5000ms ๊ธฐ๋ค๋ฆฐ ํ Result()์ Integer๋ฅผ ๋ํด 42๋ฅผ ๋ฐํํฉ๋๋ค. Wait Until ์๊ฐ ์ด๊ณผ๋ ์ค๋ฅ์
๋๋ค.
Option Explicit On
Async Function ValueLater(ByVal value As Integer, ByVal milliseconds As Integer) As Task(Of Integer)
Await Delay(milliseconds)
Return value
End Function
Sub Main()
Dim first = ValueLater(20, 30)
Dim second = ValueLater(22, 10)
Wait Until first.IsCompleted() AndAlso second.IsCompleted() Timeout 5000
Return first.Result() + second.Result()
End Sub
๋งค๊ฐ๋ณ์ ๋ฐ ์คํ ์ค๋ช :
ValueLater๋ value์ milliseconds๋ฅผ ๊ฐ์ผ๋ก ๋ฐ์ต๋๋ค. ๊ฒฐ๊ณผ๋ฅผ ์ฝ๊ธฐ ์ ์ ๋ ํธ์ถ์ ์์ํ์ฌ 10ms ํ 22, 30ms ํ 20์ ์ป์ต๋๋ค. Main์ ์ต๋ 5000ms ๊ธฐ๋ค๋ฆฐ ํ Result()์ Integer๋ฅผ ๋ํด 42๋ฅผ ๋ฐํํฉ๋๋ค. Wait Until ์๊ฐ ์ด๊ณผ๋ ์ค๋ฅ์ ๋๋ค.
2. ๋๊ธฐ ์ค ์ค๋ฅ ์ก๊ธฐ
# FailLater๋ ๊ฐ์ด ์๊ณ 5ms ํ ์ค๋ฅ๋ฅผ ๋์ง๋๋ค. ReadFailure๊ฐ Await์์ ์ด๋ฅผ ๋ฐ์ ํ
์คํธ๋ฅผ ์ ์ฅํ๊ณ Finally์์ ๊ณต์ ์ ๋ฆฌ ํ๋๊ทธ๋ฅผ ์ค์ ํฉ๋๋ค. Main์ ์ต๋ 5000ms ๊ธฐ๋ค๋ ค String "failed:1"์ ๋ฐํํฉ๋๋ค. 1์ True์ด๋ฉฐ Catch/Finally์๋ Await๊ฐ ์์ต๋๋ค.
Option Explicit On
Module State
Public Dim cleaned As Boolean = False
End Module
Async Function FailLater() As Task
Await Delay(5)
Throw "failed"
End Function
Async Function ReadFailure() As Task(Of String)
Dim message As String = ""
Try
Await FailLater()
Catch problem
message = problem
Finally
State.cleaned = True
End Try
Return message & ":" & CStr(State.cleaned)
End Function
Sub Main()
Dim task = ReadFailure()
Wait Until task.IsCompleted() Timeout 5000
Return task.Result()
End Sub
๋งค๊ฐ๋ณ์ ๋ฐ ์คํ ์ค๋ช :
FailLater๋ ๊ฐ์ด ์๊ณ 5ms ํ ์ค๋ฅ๋ฅผ ๋์ง๋๋ค. ReadFailure๊ฐ Await์์ ์ด๋ฅผ ๋ฐ์ ํ ์คํธ๋ฅผ ์ ์ฅํ๊ณ Finally์์ ๊ณต์ ์ ๋ฆฌ ํ๋๊ทธ๋ฅผ ์ค์ ํฉ๋๋ค. Main์ ์ต๋ 5000ms ๊ธฐ๋ค๋ ค String "failed:1"์ ๋ฐํํฉ๋๋ค. 1์ True์ด๋ฉฐ Catch/Finally์๋ Await๊ฐ ์์ต๋๋ค.
3. ๋ฐ๋ณต๊ณผ ๊ฒฐ๊ณผ ์ ๋ฌ
# IncrementLater(value)๋ 5ms ๊ธฐ๋ค๋ ค value+1์ ๋ฐํํฉ๋๋ค. SumLater๋ total๊ณผ i๋ฅผ ์ ์งํ๋ฉฐ i=1..3 ํธ์ถ์ ์์๋๋ก ๊ธฐ๋ค๋ฆฝ๋๋ค. ForwardResult๊ฐ Return Await๋ก 9๋ฅผ ์ ๋ฌํฉ๋๋ค. Main์ Integer 9๋ ํฉ๊ณ์ด๋ฉฐ ๋
ผ๋ฆฌ๊ฐ์ด ์๋๋๋ค.
Option Explicit On
Async Function IncrementLater(ByVal value As Integer) As Task(Of Integer)
Await Delay(5)
Return value + 1
End Function
Async Function SumLater() As Task(Of Integer)
Dim total As Integer = 0
For Var i = 1 To 3
Dim nextValue = Await IncrementLater(i)
total += nextValue
Next
Return total
End Function
Async Function ForwardResult() As Task(Of Integer)
Return Await SumLater()
End Function
Sub Main()
Dim task = ForwardResult()
Wait Until task.IsCompleted() Timeout 5000
Return task.Result()
End Sub
๋งค๊ฐ๋ณ์ ๋ฐ ์คํ ์ค๋ช :
IncrementLater(value)๋ 5ms ๊ธฐ๋ค๋ ค value+1์ ๋ฐํํฉ๋๋ค. SumLater๋ total๊ณผ i๋ฅผ ์ ์งํ๋ฉฐ i=1..3 ํธ์ถ์ ์์๋๋ก ๊ธฐ๋ค๋ฆฝ๋๋ค. ForwardResult๊ฐ Return Await๋ก 9๋ฅผ ์ ๋ฌํฉ๋๋ค. Main์ Integer 9๋ ํฉ๊ณ์ด๋ฉฐ ๋ ผ๋ฆฌ๊ฐ์ด ์๋๋๋ค.
๋ด๋ถ ํจ์: ํธ์ถ๋ถํฐ ๊ฒฐ๊ณผ๊น์ง
ํจ์๋ ์ฒซ ๋ฒ์งธ ๋ฏธ์๋ฃ Await๊น์ง ์ฆ์ ์คํํฉ๋๋ค. ์ง์ญ ๋ณ์, ๋ฐ๋ณต ์์น, With ๊ฐ์ฒด์ ๋๋ฒ๊ฑฐ ํ๋ ์์ ์ ์ฅํ๋ค๊ฐ ์ฌ๊ฐํ ๋ ๋ณต์ํฉ๋๋ค. ์ด๋ฏธ ์๋ฃ๋ ์์ ์ ์ค๋จํ์ง ์์ผ๋ฉฐ Await ํผ์ฐ์ฐ์๋ ํ ๋ฒ๋ง ๊ณ์ฐํฉ๋๋ค.
1. Delay
Delay๋ 0..2147483647 ๋ฐ๋ฆฌ์ด์ Integer๋ฅผ ๋ฐ์ต๋๋ค. 0์ ์ฆ์ ์๋ฃํ๋ฉฐ ์์, ์์์ String์ ์ก์ ์ ์๋ ์ค๋ฅ๋ฅผ ๋ ๋๋ค. ๋จ์กฐ ์๊ณ๋ก ์ต์ ๋๊ธฐ ์๊ฐ์ ์ ํ๋ฉฐ ์ ํํ ์คํ ์๊ฐ์ ๋ณด์ฅํ์ง ์์ต๋๋ค.
due = monotonicNow + milliseconds return task
ํ๋ก์ ํธ ์์ค: external/InjectionScript/src/InjectionScript/Runtime/ScriptAsyncScheduler.cs; ํจ์ Delay.
2. ResolveAwaitTask
์์ ๋ณ์๋ ํ์์ ์๋ตํ๊ฑฐ๋ As Object๋ก ์ ์ธํฉ๋๋ค. Await๋ ํ์ฌ ์คํ์ ์์ ์ ๋ ๋ฆฝ ๋ฌธ์ฅ, ๋จ์ผ ์ค์นผ๋ผ ์ ์ธ/๋์ ์ ์ ์ฒด ์ค๋ฅธ์ชฝ, Return Await๋ก ๋ฐ์ต๋๋ค. ์ฐ์ , ์กฐ๊ฑด, ํ๋/์ธ๋ฑ์ค ๋์ , Catch/Finally ๋ฐ Async Function ๋ฐ์์๋ ์ฌ์ฉํ ์ ์์ต๋๋ค. ์ฌ๋ฌ ํจ์๊ฐ ๊ฐ์ ์์ ์ ๊ธฐ๋ค๋ฆด ์ ์์ง๋ง ์ํ ์์กด์ฑ์ ์ค๋ฅ์ ๋๋ค.
validate owner and dependency chain evaluate operand once
ํ๋ก์ ํธ ์์ค: external/InjectionScript/src/InjectionScript/Runtime/Interpreter.Async.cs; ํจ์ ResolveAwaitTask.
3. ExecuteSubrutine
ํจ์๋ ์ฒซ ๋ฒ์งธ ๋ฏธ์๋ฃ Await๊น์ง ์ฆ์ ์คํํฉ๋๋ค. ์ง์ญ ๋ณ์, ๋ฐ๋ณต ์์น, With ๊ฐ์ฒด์ ๋๋ฒ๊ฑฐ ํ๋ ์์ ์ ์ฅํ๋ค๊ฐ ์ฌ๊ฐํ ๋ ๋ณต์ํฉ๋๋ค. ์ด๋ฏธ ์๋ฃ๋ ์์ ์ ์ค๋จํ์ง ์์ผ๋ฉฐ Await ํผ์ฐ์ฐ์๋ ํ ๋ฒ๋ง ๊ณ์ฐํฉ๋๋ค.
save locals, With receiver, debugger frame suspend until task completes restore saved state
ํ๋ก์ ํธ ์์ค: external/InjectionScript/src/InjectionScript/Runtime/Interpreter.cs; ํจ์ ExecuteSubrutine.
4. Pump
์คํฌ๋ฆฝํธ ์์ ์ค๋ ๋๋ ์์ ํ ํ์ธ ์ง์ ์์ ๊ธฐํ์ ๊ฒ์ฌํ๊ณ ํ ํ์ ์ต๋ 64๊ฐ์ ์ค๋น๋ ๊ณ์ ์์ ์ ์คํํฉ๋๋ค. ์ ์ค๋ ๋๋ ์์ต๋๋ค. ๋๊ธฐ Wait๋ ์ค๋ ๊ฑธ๋ฆฌ๋ ๊ฒ์/๋ค์ดํฐ๋ธ ํธ์ถ์ ๋ค๋ฅธ ์์ ์ ์ง์ฐ์ํฌ ์ ์์ผ๋ฏ๋ก Await Delay๋ฅผ ์ฌ์ฉํ์ธ์. ๋ฏธ์๋ฃ ์์ ๋๋ ์์ง ์ฝ์ง ์์ ์คํจ ์์ ์ ์ต๋ 1024๊ฐ์ ๋๋ค.
if earliest deadline reached: complete delays resume at most 64 queued continuations refresh function results
ํ๋ก์ ํธ ์์ค: external/InjectionScript/src/InjectionScript/Runtime/ScriptAsyncScheduler.cs; ํจ์ Pump.
5. GetResult
IsCompleted๋ ์ฑ๊ณตยท์คํจยท์ทจ์ ํ 1, IsFaulted๋ ์คํจ ์ 1, IsCanceled๋ ์ทจ์ ์ 1์ ๋๋ค. ์ด Integer ์กฐ๊ฑด์ True/False์ ๋น๊ตํ ์ ์์ต๋๋ค. Result()๋ ์ ์ฅ๋ ๊ฐ์ ๋ฐํํ๊ณ ๋ฏธ์๋ฃ๋ฉด ์ค๋ฅ, ์คํจํ์ผ๋ฉด ์๋ ์ค๋ฅ๋ฅผ ๋ค์ ๋์ง๋๋ค. ์ด์ ์คํ์ ์์ ์ ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
if pending: error if failed: rethrow return saved value
ํ๋ก์ ํธ ์์ค: external/InjectionScript/src/InjectionScript/Runtime/ObjectTypes/ScriptTaskObject.cs; ํจ์ GetResult.
6. Release
์ผ์ ์ ์ง๋ ๊ณ์ ์คํ์ ๋ง์ง๋ง ์๊ฐ์ ํ๋ฆ ๋๋ค. ์ฌ๊ฐํ๋ฉด ๊ธฐํ์ด ์ง๋ ์์ ์ ์ฒ๋ฆฌํฉ๋๋ค. Stop, ์ค๋ฅ ๋๋ ์ง์ ์ ๋ฐํ์ ๋จ์ ์์ ์ ์ทจ์ํ๊ณ Using ์์๊ณผ ๋ฐ๋ณต์๋ฅผ ํด์ ํฉ๋๋ค. ๋น์ ์ทจ์๋ ์คํฌ๋ฆฝํธ Catch/Finally๋ฅผ ๊ฑด๋๋๋๋ค. ์ฝ์ง ์์ ์์ ์ค๋ฅ๋ ์ง์ ์ ์ข ๋ฃ ์ ๋ณด๊ณ ๋ฉ๋๋ค. IDE๋ง ๋ซ์์๋ ์คํ ์ค์ธ ์คํฌ๋ฆฝํธ๊ฐ ๋ฉ์ถ์ง ์์ต๋๋ค.
cancel pending tasks drain cleanup continuations release resources report unobserved failure
ํ๋ก์ ํธ ์์ค: external/InjectionScript/src/InjectionScript/Runtime/ScriptAsyncScheduler.cs; ํจ์ Release.
์คํฌ๋ฆฝํธ์์ Async Function๊ณผ Delay๋ฅผ ํธ์ถํ๋ฉด ์ฆ์ T๊ฐ ์๋ Object (ScriptTask)๋ฅผ ๋ฐ์ต๋๋ค. Await์ Result()๋ T๋ฅผ ๋ฐํํ๋ฉฐ As Task์ Delay๋ ๊ฐ ์๋ Unit์ผ๋ก ๋๋ฉ๋๋ค. ํด๋ผ์ด์ธํธ๊ฐ Async Function์ ์ง์ ์ ์ผ๋ก ์คํํ๋ฉด ํ๋ ฅ์ ์ผ๋ก ๊ธฐ๋ค๋ ค ์ต์ข ๊ฒฐ๊ณผ๋ฅผ ๋ฐ์ต๋๋ค. ์ซ์ ๋ฐ์ดํฐ๊ฐ ํญ์ Boolean์ธ ๊ฒ์ ์๋๋๋ค.