Swift 24 スイフト構造化された同時性概要

concurrencyは複数の作業を並列に実行するソフトウェア機能で定義できます。多いアフリ開発プロジェクトはある時点で同時処理をしようしかならないし、良い使用者経験を提供する為に必須的です。
今度の章にはスイフトプログラミング言語のStructeredconcurrency機能を見てみてそのような機能を使用してアプリプロジェクトでもマルチタスクサポートする方法を説明する

# 24.1 スレッド概要
threadは現代CPUの機能で全てのMultitaskingOperatingSystemで同時性をの基盤を提供します。現代CPUは複数のスレッドを実行することができますが、一度で並列で実行できる実際の数はCPUコーアの数で制限されます・CPUのモデルによって一般的に4から16コーア。**CPUコーアよりより多くスレッドが必要な場合にOperatingSystemはスレッドスケジュりんぐをを実行**して、これらのスレッドの実行を使用可能されるコーア間にどのように共有するかを決めます。

スレッドは**メインプロセス内で実行されるミニプロセス**と考えられることができますし、その目的はアフリの**コード内で並列実行の形を可能される様**にすることです。構造化された同時性がバックラウンドでスレッドを使用しますが全ての複雑性を処理するので自身が直接に相互作用するひつよはありません。

# 24.2 アフリのメインスレッド
アフリが初めて開始時ランタームシステームは**普段アフリが基本的に実行される単一のスレッド**を生成します。このスレッドを`MainThread`だといいます。主要役目はUIレイアウトレンダリング、イベント処理及び使用者インタフェイスでビューと使用者相互昨業の面では使用者インタフェースを処理することです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/c8510711-a177-619a-1927-ef8124f04d67.png)
メインスレッドを使用して時間消耗的な作業を実行するアフリ内の方のコードは時間消耗的な作業が完了するまで全体アフリが止まる様に見えます。此れは、メインスレッドが他の作業を妨害されずに続くられるように実行する作業を別度のスレッドで初めて避けれます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/eae6fada-996e-3489-b82f-5ff853cfa98b.png)
# 24.3 completion handler 
Swiftはこれを使ってasynchronous codeを実装されました。ここではasynchronous operationsが開始され作業が完了したら呼び出される様に`完了ハンドラー`が割り振られます。反面、`メインアフリコード`は非同期作業がバッグラウンドで実行される間に継続的に実行されます。asynchronous operationsがが完了したら`完了ハンドラー`が呼び出されて結果を伝達されます。そうすると`完了ハンドラー`の本文で該当結果を処理します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/ef9436f7-0179-95fd-ed95-5482662e9175.png)
残念ながらcompletion handlerは作成及び理解が難しいアーラが発生しやすいコード構成をもたらすことがあります。またcompletion handlerは`asynchronous作業で発生するエラーを処理に適していないし一般的に大きくて複雑な重畳コードが作成されます。
# 24.4 `ストラクト`化されたasynchronous
此れはスイフト5.5で導入されてアフリ開発者が同時実行をより簡単に実行されます。言い直して、`ストラクト`化された同時性コードはロジク流れを理解するためにcompletion handlerをコードで再移動必要なくて上から下で読むことができます。また、`ストラクト`化されたasynchronousは`非同期func(){     }`で発生されるエラーをより易く処理することができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/fb10d646-489a-f082-52cd-61238ec8b559.png)
# 24.5 プロジェクト準備する
```swift
struct ContentView: View {
    var body: some View {
        Button(action:{
            doSomething()
        }){
            Text("Do something")
        }
    } //var body
    func doSomething(){
        
    }
    func takesTooLong(){
        
    }
}　//struct ContentView

struct ContentView_Previews: PreviewProvider {
    static var previews: some View{
        ContentView()
    }
}
```
# 24.6 asynchronousコード
> a・synchro・nous :
?  not existing or happening at the same time.

```diff_swift
 func doSomething(){
+        print("Start\(Date())")
+       takesTooLong()
+       print("End\(Date())")
    }
    func takesTooLong(){
+        sleep(5)
+        print("Async task completed at \(Date())")
    }
```
* sleep()
はfunctionが*完了されるまでにメインスレッドをブロックする時間がかかる作業を実行る*効果をシミュレーターします。
```swift
Start2023-11-14 06:14:43 +0000
Async task completed at 2023-11-14 06:14:48 +0000
End2023-11-14 06:14:48 +0000
Start2023-11-14 06:14:48 +0000
```
このタイムスタンプで主目するプインとは終了時間が始める時間後５秒だとということです。此れは **`doSomething()function`内で呼ばれた後の全てのコードが呼び出しが返されるまで実行しなかった**と知らせます。使用者には５秒間アフリが止まれる様に見えます。
これはasync/await `同時性ストラクト`を実行して解決できます。
# 24.7 async/await 同時性紹介
`ストラクト`された同時性の基本は`async/await`組である。asyncキーワード`func(){     }`が呼び出されたスレッドに対して非同期的に実行されるを表示する為に`func`を宣言する時に使用者されます。従って二つの例題全てを次の様に宣言するしなければなりません
```diff_swift
+ func doSomething()async{
        print("Start\(Date())")
        takesTooLong()
        print("End\(Date())")
    }
+ func takesTooLong()async{
        sleep(5)
        print("Async task completed at \(Date())")
    }
```
`func(){     }`をasyncで表示すればあるいくつかの目標を達成することができます。まず此れは`func(){     }`のコードが呼び出される**スレッドと他のスレッドで実行するべきを現れ**ます。
またシステムが他の作業を実行する様に実行する間に`func(){     }`自体が一時停止されることをシステム知らせます。

async関数に対して主意することは、他のasync関数範囲内に限って呼び出すことです。今度の章の後方からご覧の通り`Taskオブジェクト`は`syncコード`と`asyncコード`間の橋を提供するに使用されることができます。最後に`async関数`他の`async関数`呼び出す場合に、全ての下位作業も完了されるまでに上位関数を終了できません。
一番大事なことは`func(){     }`がasyncで**宣言されるとawaitキーウードを通じて呼び出されること**です。

# 24.8 sync関数でasync関数呼び出す
`ストラクト`されたsync性の規則は`async関数`の`asyncコンテキスト`内でだけで呼び出されることを現れます。プログラミングの進入点が`sync関数`なら、`async関数`がどうして呼び出せるかと疑問が生じます。その答えは`sync関数`内で`Taskオブジェクト`を使って`async関数`を始めることです。次の様に一つの`async関数`を呼び出そうとするmain()という`sync関数`があると仮定しましましょう。
```diff_swift
func main(){
doSomething()
}
```
此れはこのエラーを通知を表示します。
```swift
async' call in a function that does not support concurrency
```
いまできる唯一な選択肢はmain()を`async関数`に作るとか`ストラクト`されなかった作業でmain()関数を始めることです。main()をasync関数で宣言することが実行可能な選択肢では無いと仮定すると、この場合には
```diff_swift
func main(){
+        Task{
+           await doSomething()
+        }
}
```
変更します。
# 24.9 awaitキーウード
前で明したように、`awaitキーウード`は`async関数`を呼び出す時に必要であり、一般的に他の`async関数`範囲無いだけで使用されます。これなして`async関数`を呼び出するようにすると
```swift
Expression is 'async' but is not marked with 'await'
```
従って takesTooLong()関数を呼び出にはdoSomething()関数を変更が必要です。
```diff_swift
 func doSomething()async{
        print("Start\(Date())")
+       await takesTooLong()
        print("End\(Date())")
    }
```
`syncコンテキスト`・ここではButtonビューのactionClosure・で`async doSomething()`呼び出そうとするので、もう一度変更するべきです。この問題を解決するために`taskオブジェクト`を使ってdoSomething関数を始めるべきです。
```diff_swift
start2023-11-14 08:57:53 +0000
Async task completed at 2023-11-14 08:57:58 +0000
End2023-11-14 08:57:58 +0000
```
ここでawaitキーウードが混乱するかもしれない、doSomething()関数は続行出来ずにtakesTooLong()関数が返却されるまで待ちするしか無いので、作業を呼び出したスレッドをまだ、阻止しているという印象を与える。実は作業は他のスレッドで行われましたが**awaitキーウードは作業が完了されるまでに待ってとシステムに要求**するすることです。そうなった理由は前で前述したように**スーパー`async関数`は全てのサーブ関数が完了されるまでに完了し無い**からです。その言葉はtakesTooLong関数次であるコードラーインが実行される前に`async　takesTooLong()`関数が返却される時まで待つすること以外には選択の余地がないことを意味します。次の節ではasync-let`バインディング表現式を使ってスーパー関数から待つことを後回しにする方法を説明します。だがそうする前にことコンテキストでawaitキーウードを使用するまたもう一つの効果を見る必要があります。

`asyncCall`を許可すること以外にも**awaitキーウードはdoSomething()関数内で一時的な中断点**を定義します。実行間にこの点に到達すると、doSomething()関数は一時的に止められることになり、実行中のス**レッドに他の用途として使用されることを、システムに知らせ**ます。これを通じてシステムは優先順位がもっと高い作業でリソースを割り合うことが出来ますし、後でdoSomething()関数を制御を`↑ return`して**実行を続くられる様にします**。一時中断点を表示してdoSomething()関数はシステムが他の作業処理でリソースを一時割り当てられる様にして基本的にアプリの性能を良くします。システムの速度を考えると一時中断は１秒以上続けしなければアフリの全体性能に役立ちながら使用者目に留まらないことです。

例題コードで`awaitキーウード`を基本動作は実行を再開する前に呼び出された関数が`↑ return`される前まで待つすることです。しかしもっと一般的な要求事項は`async関数`がバッグラウンドで実行される間に呼び出す関数の内でコードを継続実行することでする。此れは`async-letバインディング`を使用して該当コードで後日まで持つことを引き摺れてできます。これを見せるために、まずtakesTooLong()関数が結果を・ここでは作`業完了タイムスターンプ`・を`↑ return`される様に修正しましょう。

```diff_swift
+ func takesTooLong() async -> Date {
         sleep(5)
+        return Date()
}
```
次で、`↑ return`された結果をlet式を使用するだけど`asyncキーウード`で表示される変数で割り当うためにdoSomething()内呼び出すこと変更するべきです
```diff_swift
func doSomething()async{
        print("Start\(Date())")
-       await takesTooLong()
+       async let result = takesTooLong()
        print("End\(Date())")
    }
```
これで、doSomething()関数内で結果値が`↑ return`された時前まで待機する場所を指定するだけでいいです。awaitキーウードを使ってresult変数で接近してこれを実行します。
```diff_swift
func doSomething()async{
        print("Start\(Date())")
        async let result = takesTooLong()
+        print("After async-let \(Date())")
        //비동기 함수와 동시에 실행할 추가 코드가 여기에 온다
+        print("result = \(await result)")
        print("End\(Date())")
    }
```
結果値を出力時に、`async takesTooLong()`関数が結果値を`↑ return`されるまで、実行を続けられないことをシステムに知らせる為にawaitを使用者しています。この時点で結果を使えるようになるまで実行が中止されます。しかし、`async-let`と`await`間の全てのコードはtakesTooLong()関数と同時に実行されます。
```diff_swift
Start2023-11-15 05:23:01 +0000
After async-let 2023-11-15 05:23:01 +0000
result = 2023-11-15 05:23:06 +0000
End2023-11-15 05:23:06 +0000
```
`after async-let`メッセージには`result =`  `↓ call`が`↑ return`されるタイムスタンプより５秒早いタイムスタンプがあるのでtakesTooLong()が実行される間にコードが行われたことを確認できます。
![GUEST_6045fc0c-6e10-4cd1-be45-91f61d61a595.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513806/c302e40c-4e60-b675-4afc-da2e32317a27.jpeg)

# 24.11 エラーハンドリング
`ストラクト`化された同時性のエラーハンドリングは　throw/do/try/catch メカニズムを使用します。次の例題は既存の`async　takesTooLong`関数を修正してし遅延されたが特定範囲を超えるとエラーを発生します。
```diff_swift
+enum DurationError: Error{
+        case tooLong
+        case tooShort
+    }
    
    func takesTooLong(delay: UInt32) async throws {
+        if delay < 5 {
+            throw DurationError.tooShort
+        } else if delay > 20 {
+            throw DurationError.tooLong
+        }
+       sleep(delay)
-       sleep(5)
+       print("Async task completed at \(Date())")
-       return Date()        
    }
```
これで関数が`↓ call`さればdo/try/catch 構文を使用してエラーを処理することができます。
```diff_swift
func doSomething()async{
        print("Start\(Date())")
        do {
            try await takesTooLong(delay: 25)
        } catch DurationError.tooShort {
            print("Error: Duration too short")
        } catch DurationError.tooLong {
            print("Error : Duration too Long")
        } catch {
            print("UnknownError")
        }
        print("End\(Date())")
    }
```
実行された結果は次の様に出力されます。
```diff_swift
Start2023-11-15 06:49:39 +0000
Error : Duration too Long
End2023-11-15 06:49:39 +0000
```
# 24.12 Task理解する　
**`async⌥`で実行される全ての作業はスイフトの`Taskクラス`のインスタンス内で実行されます**。アフリは複数の作業を同時に実行されるし、そのような作業を`Hierachy`で構成することができます。
今度の章のアフリでバートンが押されると`async⌥`バージョンのdoSomething()関数が`Taskインスタンス`内で実行されます。takesTooLong()関数が`↓ call`されるとシステムは関数コードが実行される`サーブ作業`を生成します。`作業HierachyTree`側面でこの`サーブ作業`は`スーパー作業`のdoSomething)のサーブです。`サーブ作業`内で全ての`async⌥`関数`↓ call`は該当作業のサーブになるようなものです。

この作業`Hierachy`構造は`ストラクト`された`sync`性が構築される基盤を形成します。例えば`サーブ作業`はスーパーからプライオリティと同じ属性を継承して`Hierachyストラクト`は全ての`サーブ作業`がが完了される時まで`スーパー作業`が終了しないようにします。

# 24.13 `ストラクト化`されていない`sync`
此れはTaskオブジェクトを使って個別の作業を直接に作ることができます。すでに見たように、`ストラクト化`されない作業の一般的な用途は`sync関数`内で`async⌥関数`を`↓ call`することです。

`ストラクト化`されてない作業はいつでも外部で取り消すことができますし持つと多い柔軟性には作業を作くて管理する為に、もっと多い作業を実行しなければならない側面で少しの付加的努力が必要です。

`ストラクト化`されてない作業は `Taskイニシャライザー`を`↓ call`して実行されるコードが含まれた`クロージャー`を提供して生成されて初まります。
```diff_swift
Task{
await doSomething()
}
```
また、その様な作業はactor context、プライオリティ、作業ローカル変数などと`↓ call`される`スーパーストラクト`を継承します。作業を作るときに、作業で新しいプライオリティを指定することもできます。
```diff_swift
Task(priority: .high) { 
await doSomething()
}
```
此れは他の作業と関連して、作業をどの様に予定を立ルでに対する暗示をシステムに提供します。一番高いものから一番低いものまで
* .high / .userInitiatied 
* .low/ .utility
* .medium
* .background
作業が直接に生成されると`Taskインタフェイス`に対するプリファランスを`↓ call`します。此れは作業を取り消すするとか、作業範囲外部からでにキャンセルされたかどうかどうかを確認するに使用されることができます。
```diff_swift
Task(priority: .high) { 
await doSomething()
}
.
.
if (!task.isCancelled) {
    task.cancel()
}
```
# 24.14 分離された作業
detached taskは`ストラクト`化しれない同時性のまた他の形で`↓ call`する`スーパー`から属性を`インヘリット`しない点で、`ストラクト`しなかった同時性と違い点があるます。分離された作業はTask.detached()を`↓ call`されて生成します。
```diff_swift
Task.detached{
    await doSomething()
}
```
分離された作業でもプライオリティ値が伝達されることがあるし、前で説明したものと同じ技術を使用してキャンセルの有無を確認できます。
```diff_swift
let detachedTask = Task.detached(priority: .medium) { 
await doSomething()
}
.
.
if (!detachedTask.isCancelled) {
    detachedTask.cancel()
}
```
<a href="https://www.hackingwithswift.com/quick-start/concurrency/whats-the-difference-between-a-task-and-a-detached-task">What’s the difference between a task and a detached task?</a>
> If you create a new task using the regular Task initializer, your work starts running immediately and inherits the priority of the caller, any task local values, and its actor context. On the other hand, detached tasks also start work immediately, but do not inherit the priority or other information from the caller.

# 24.15 Task管理
`ストラクト{}`された作業を使用されるか、または`ストラクト`化されない作業を使用すると関係なく、`Taskクラス`は作業範囲内で作業を管理する為に使用される一連の`staticメソッド`を提供します。例えば作業は生成される時に割り当てたプライオリティをし区別する為にcurrentPriority属性を提供します。
```diff_swift
Task{
    let priority = Task.currentPriority
    await doSomething
}
```
残念ですけど此れは読み取り専用属性で、実行中ている作業のプライオリティを変更する為に使用できません。`isCancelledプロパティ`に接近して作業が取り消したのかを確認できます。
```diff_swift
    if Task.isCancelled {
    //作業正理修行
    }
```
キャンスルを感じするまた他の選択肢は、作業が取り消した場合にはCancellationErrorエラーを発生させるcheckCancellation()`メソッド`を`↓ call`する事です。
```diff_swift
do{
    try Task.checkCancellation()
    } catch {
    //作業し正理修行
}
```
Task `メソッド`の　cancel()`↓ call`していつでも自身の作業をキャンセル事ができます。
```diff_swift
Task.cancel()
```
最後に、作業コード内で実行を安全に一時中断することができる位置が有ればyield()`メソッド`を通じてシステムに宣言できます。
```diff_swift
Task.yield()
```
# 24.16 Task グループ
今まで例題は一つまたは二つの作業(`スーパー` `サーフ`)を作る事でした。それぞれの場合には、私たちはコードを作成する前にどのくらいの作業が必要かを学びました。しかし動的な条件に従って、複数の作業を同時に生成して実行する必要がある状況がしばしば発生します。例えば、配列の格項目とか`forルーフ` 中て別度の作業を開始する必要がある場合があります。
スイフトはTaskグループを提供してその様な状況を解決します。

作業グループを使うと可変的な数の作業を生成してwithThrowingTaskGroup()またはwithTaskGroup()関数を使って実装される様にします。その後、作業を生成する為のルーフ構造が該当クロージャー内で定義してaddTask()関数を`↓ call`してそれぞれの新しい作業を追加します。

次の様に二つの関数を修正してそれぞれのtakesTooLong()関数のインスタンスを実行する五つの作業で構成された作業グループを作りましょう
```diff_swift
   func doSomething()async{
        await withTaskGroup(of: Void.self){group in
            for i in 1...5 {
                group.addTask {
                    let result = await takesTooLong()
                    print("Completed Task \(i) = \(result)")
                }
            }
        }
    }
    
    func takesTooLong() async -> Date{
        sleep(5)
        return Date()
    }
```
前のコードを実行すると次の様な結果が表示される前に作業が実行されている間５秒遅延が発生するだろう。
```diff_swift
Completed Task 5 = 2023-11-16 05:28:36 +0000
Completed Task 3 = 2023-11-16 05:28:36 +0000
Completed Task 4 = 2023-11-16 05:28:36 +0000
Completed Task 2 = 2023-11-16 05:28:36 +0000
Completed Task 1 = 2023-11-16 05:28:36 +0000
```
作業は全て同時に実行されたことを現れる同時な完了タイムスタンプを表示されます。作業が開始された順序通りに完了していないという点もあります。同時性を使用して作業するときTaskが生成された順序通りに完了される保証がいない点も心に留めておくことが重要です。

addTask()関数意外にも次を含まれて作業のグループ内で接近できる幾つの`メソッド`と属性があるます。
* cancelAll() - グループの全ての作業をキャンセルする`メソッド` `↓ call`
* isCancelled - 作業グループがすでにキャンセルされたかの有無を示すboolプロパティ
* isEmpty - 作業グループ内で作業が残っているかを有無を示すboolプロパティ

# 24.17 データ競争避ける
前のTaskグループの例題でグループはTaskの結果を保存しないです。言い直して結果はTaskグループの範囲を逸脱せずTaskが終了されば維持もされないです。例えば、各作業に対する作業番号と結果タイムスタンプをスイフトのデックショナリオブジェクトで保存したいと仮定しましょう。同期コードで作業すると次のような方法を考えられることができます。
```diff_swift
 func doSomething()async{
        var timeStamps: [Int: Date] = [:]
        await withTaskGroup(of: Void.self){group in
            for i in 1...5 {
                group.addTask {
                 timeStamps[i] = await takesTooLong()
                }
            }
        }
    }
```
残念だけとエラーを表示します。
```diff_swift
Mutation of captured var 'timeStamps' in concurrently-executing code
```
ここで問題は同時にデータに接近する複数の作業があるしdata race条件が発生される危険があることです。これは複数の作業が同時に同一なデータに接近を試みて、この様な作業の中で一つ以上の作業が書き作業を実行する時に発生します。此れは一般的に診断が難しいデータ破損問題が発生します。

一つの選択肢はデータを保存するactorを作ることです。actor及びその様な特定問題を解決する為に使用者される方法は25章で紹介します。

他の方法には作業結果を順序的に`↑ return`してディクショナリー で追加される様に作業グループを調整することです。元々はwithTaskGroup()関数の`↑ return`ターフを次の様にVoid.selfにして作業グループを結果を`↑ return`しないと宣言した。
```diff_swift
await withTaskGroup(of: Void.self) { group in
```
最初は、格TaskがTask番号(Int)とタイムスタンプ(Date)を含まれるTupleを`↑ return`される様に次の様に作業グループを設計することです。
```diff_swift
  func doSomething()async{
        
        var timeStamps: [Int: Date] = [:]
        
        await withTaskGroup(of:(Int, Date).self){group in
            for i in 1...5 {
                group.addTask {
                 return(i, await takesTooLong())
                }
            }
        }
    }
```
次にはグループで`↑ return`された結果を処理する為に２番目のルーフを宣言するべきです。結果は`async⌥関数`個別的に`↑ return`されて、一度にすべての結果を処理するように簡単にループを作成できない。かく結果が`↑ return`される時まで持ちするべきです。その様な場合スイフトはfor-waitループを提供します。

# 24.18 for-await ループ
for-await 表現式を使用すると`async⌥`的に`↑ return`される一連の値を一つずつループを回す事ができ、同時作業で`↑ return`される値の受信を待ちことができます。for-awaitを使用するための唯一な要求事項は一連のデータが`AsyncSequenceプロトコル`準拠することです。

例題では作業グルぷ範囲の中でaddTaskループ次にfor-awaitループを次のように追加するべきです。
```diff_swift
   func doSomething()async{
        
        var timeStamps: [Int: Date] = [:]
        
        await withTaskGroup(of:(Int, Date).self){group in
            
            for i in 1...5 {
                group.addTask {
                 return(i, await takesTooLong())
                }
            }
+            for await (task, date) in group{
+                timeStamps[task]=date
+            }
        }//withTaskGroup
    }
```
各作業が`↑ return`されるとfor-awaitループは結果tupleを受信してtimeStampsディクショナリーで保存します。これを確認する為に作業グループが終了された後でディクショナリー項目を出力する少しのコードを追加しましょう。
```diff_swift
            for await (task, date) in group{
                timeStamps[task]=date
            }
        }//withTaskGroup
        
+        for (task, date) in timeStamps {
+            print("Task = \(task), Date = \(date)")
+        }

>>
Task = 5, Date = 2023-11-16 07:23:36 +0000
Task = 1, Date = 2023-11-16 07:23:36 +0000
Task = 4, Date = 2023-11-16 07:23:36 +0000
Task = 3, Date = 2023-11-16 07:23:36 +0000
Task = 2, Date = 2023-11-16 07:23:36 +0000
```
#24.19 `async⌥`プロパティ
`async⌥`関数ではなく、スイフトはクラスと`ストラクト`タープ内で`async⌥`プロパティもサポートします。次の例題には`async⌥`プロパティはgetterを明示的に宣言してasync表示で生成されます。現在には読む専用プロパティだけ`async⌥`になることができます。
```diff_swift
struct MyStruct {
        var myResult: Date{
            get async {
                return await self.getTime()
            }
        }
        
        func getTime() async -> Date {
            sleep(5)
            return Date()
        }
    }
    
    func doSomething()async{
        
        let myStruct = myStruct()
        Task {
            let date = await myStruct.myResult
            print(date)
        }
    }
```
# 要約
現代CPUとOperatingSystemは同時に複数の作業を修行される様にコードが同時に行うように設計されました。此れは使用者インタフェイスをレンダリングする事と、使用者イベントで応答するし事を主にメインスレっとが担当して、他のスレッドにはその他の作業を実行することで可能になります。基本的にアフリの大部分のコードは他のスレッドで実行される様に特に設定しない限りメインスレッドでも実行されます。該当コードがあまりにも長い間メインスレッドを占有する作業を実行すると、作業が完了される時までアフリが止まったように見えます。これを避けるためにスイフトは`ストラクト`化された同時性APIを提供します。これを使う時にメインスレッドを遮断するコードは別度のスレッドに行う様に`async⌥`関数・`asyncプロパティ`も支援・で配置されます。`↓ call`するコードはawaitキーウードを続く使用する前に`async⌥`コードが完了される時までに待つようにさせるとか、async-letを使用して結果が必要な時まで継続行われる様に構成されることができます。

作業は個別的にまたは複数の作業のグループの形で実行されることができます。for-awaitループは`async⌥`作業グループの結果を非同期的に処理する有用な方法を提供します。同時性で作業する時にはデータ競争を避ける事が大事で、普段はスイフトのActorを使って解決できます。