> For the complete documentation index, see [llms.txt](https://kurohasu.gitbook.io/fsharpabout/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://kurohasu.gitbook.io/fsharpabout/compute/tasuku.md).

# タスク式

### タスク式とは？

タスク式は.NETタスクを直接作成し非同期式と同様に他の作業を止めることなく非同期的に実行します\
.NETのTask<>型と互換性があるため、System.Threading.Tasks.Taskの機能も使用できます\
そのため.NETライブラリと連携させる場合はタスク式を使用することが推奨されています

```
構文:task{タスク式...}
task{
    タスク式...
}
```

### タスク式のバインド(割り当て)

タスク式は非同期のものと同期のものの2種類に分かれています\
そのため非同期処理の結果を待機(await)するにはlet!やdo!などの[コンピューテーション式](/fsharpabout/compute/konpytshon.md)を使用します

以下はタスク式におけるletとlet!の違いです

```fsharp
//ストリームより非同期に読み取るstream.AsyncRead()を例にします
let result1:Task<byte[]>=stream.AsyncRead()
//->result1はAsyncRead()を非同期実行するタスクとして保存される

let! result2:byte[]=stream.Asyncread()
//->result2はAsyncRead()を非同期実行し値を戻す
```

### 非同期式をタスク式に

前ページで紹介した非同期式をタスク式に、タスク式を非同期式にすることができます

```fsharp
//①非同期式をタスク式に
Async.StartAsTask <非同期式>

//②タスク式を非同期式に
Async.AwaitTask <タスク式>
```

### タスクから値を取得する

タスク式から値を得るには２つの方法があります\
①ValueTask<>を使用する\
「ValueTask<データ型>」と記述することでタスク式から値を得ることが出来ます\
\
②Resultメソッドを使用する\
タスク式のメソッドであるResultを使用することでも値を得ることが出来ます\
(個人的にこちらがおすすめです)

```fsharp
//呼び出すタスク式(3を返す)
let BaseTask()=task{return 3}

//①ValueTask<>を使用する
let VT=BaseTask()|>ValueTask<int>
printfn "VT=%d" VT    //出力結果:VT=3


//②Resultメソッドを使用する
let Res=BaseTask().Result
printfn "Res=%d" Res    //出力結果:Res=3
```

{% hint style="info" %}
必要に応じてスレッドプールを切り替える「backgroundTask」というのもサポートしています
{% endhint %}

### タスク式で使えるAsyncメソッド

タスク式に対応しているAsyncメソッドがいくつかあります

#### Async.StartImmediateAsTask

非同期式を現在のスレッドからタスクとして開始します

```fsharp
//構文:Async.StartImmediateAsTask <非同期式>　(キャンセルトークン)
//例:3秒後に30を返す非同期式をタスクとして実行
let back30=    //back30に非同期式の割り当て
    async{
        do! Async.Sleep 3000
        printfn "30を返します"
        return 30    
    }
    
//呼び出し
let num=(back30|>Async.StartImmediateAsTask).Result
printfn "num=%d" num    //出力結果:30
```

#### Async.StartChildAsTask

非同期式内で別の非同期式をタスクとして実行するときに使用するときに使用します

```fsharp
//構文:Async.StartChildAsTask <非同期式>
//例:

let child=
    async{
        do! Async.Sleep 2000
        printfn "childが呼び出されました"
        return ()
    }
    
let call=
    async{
        Async.StartChildAsTask child|>Async.Ignore    
    
    }    
```
