> For the complete documentation index, see [llms.txt](https://docs.skail.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.skail.dev/construir/sdk-.net/skailtask-e-skailtask-less-than-t-greater-than.md).

# SkailTask e SkailTask\<T>

O tipo de retorno de todo método decorado. Comporta-se como `Task`/`Task<T>` para quem escreve o código e, por baixo, permite ao runtime interceptar cada `await` para consultar e gravar o histórico da execução.

## Declaração

```csharp
public async SkailTask MetodoSemRetorno(...)
public async SkailTask<T> MetodoComRetorno(...)
```

Substitui `Task` e `Task<T>` nas assinaturas de `[SkailFunction]` e `[SkailCommand]`. Não é usado fora de métodos decorados.

## O que funciona igual a Task

`await`, `try/catch`, `try/finally`, `using`, LINQ sobre coleções de `SkailTask<T>`, encadeamento de chamadas, exceções tipadas. Do ponto de vista de quem lê o código, a única diferença é o nome no retorno.

## O que é diferente

| Em Task                                           | Em SkailTask                                                                                                                                                                                       |
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `.Result`, `.Wait()`, `.GetAwaiter().GetResult()` | Proibidos. Bloqueiam e quebram a hibernação; o analyzer aponta `.GetResult()` (SKAIL003). Sempre `await`                                                                                           |
| `Task.Delay`, `Task.WhenAll`, `Task.WhenAny`      | Dentro de function, use `SkailTask.Delay`, `SkailTask.WhenAll`, `SkailTask.WhenAny`; as versões `Task` não gravam passo e quebram o replay. Dentro de command, as versões `Task` são permitidas    |
| Passar como argumento                             | Um `SkailTask` não é serializável: não pode ser argumento de function nem de command                                                                                                               |
| Misturar com `Task`                               | Um helper `async Task` com I/O chamado de uma function não é durável: não grava passo, não retenta, não hiberna. Tudo no caminho durável é function, command ou `SkailTask.*`                      |
| Criar sem `await`                                 | Permitido para compor com `WhenAll`/`WhenAny`; mas toda `SkailTask` criada precisa ser aguardada em algum ponto, direto ou via composição. Uma `SkailTask` que hiberna sem ser aguardada fica órfã |

## Métodos estáticos (primitivas)

| Método                                                                | Descrição                                                                              |
| --------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| `SkailTask.Delay(TimeSpan)`                                           | Espera durável. Ver [Delay](/construir/sdk-.net/delay.md)                              |
| `SkailTask.DelaySeconds(ulong)`, `SkailTask.DelayMinutes(ulong)`      | Atalhos de `Delay`                                                                     |
| `SkailTask.WhenAll(params SkailTask[])`                               | Espera todas. Ver [WhenAll e WhenAny](/construir/sdk-.net/whenall-e-whenany.md)        |
| `SkailTask.WhenAny(params SkailTask[])`                               | Devolve a primeira concluída                                                           |
| `SkailTask.WaitForEvent(string eventName, string eventInstanceId)`    | Hiberna até um evento externo. Ver [WaitForEvent](/construir/sdk-.net/waitforevent.md) |
| `SkailTask.WaitForEvent<T>(string eventName, string eventInstanceId)` | Idem, com payload tipado                                                               |

Não existe primitiva para disparar eventos ou iniciar execuções: isso é a API HTTP.

## Como funciona por baixo

`SkailTask` tem um method builder próprio (o mecanismo que o C# usa para compilar métodos `async`). É esse builder, injetado no build pelo pacote `Skail.Platform.Runtime.Build`, que dá ao runtime o controle de cada `await`: consultar o histórico, devolver o resultado gravado ou executar e gravar, hibernar em um delay ou espera. Por isso o método precisa ser `async` (SKAIL002) e por isso `Task` não serve (SKAIL001): sem o builder, não há replay.

## Exemplo

```csharp
[SkailFunction]
public async SkailTask<Relatorio> Fechar(Guid loteId)
{
    var itens = await CarregarItens(loteId);                        // SkailTask<Guid[]>: await direto

    var processamentos = itens.Select(Processar).ToArray();          // SkailTask<Resultado>[]: criadas sem await
    await SkailTask.WhenAll(processamentos);                         // aguardadas em composição

    var resultados = new List<Resultado>();
    foreach (var p in processamentos) resultados.Add(await p);       // resultado gravado, sem esperar de novo

    return new Relatorio(resultados);
}
```

## Erros relacionados

| Erro                             | Causa                                             |
| -------------------------------- | ------------------------------------------------- |
| SKAIL003                         | `.GetResult()` em `SkailTask`                     |
| SKAIL001                         | `Task` no lugar de `SkailTask` em método decorado |
| `SkailNonDeterministicException` | `Task.Delay`/`Task.WhenAll` dentro de function    |
| Exceção de serialização          | `SkailTask` passado como argumento                |

## Veja também

[Modelo de programação](/aprender/fundamentos/modelo-de-programacao.md), [SkailFunction](/construir/sdk-.net/skailfunction.md), [SkailCommand](/construir/sdk-.net/skailcommand.md), [Regras do analyzer](/construir/sdk-.net/regras-do-analyzer-skail001-skail002-skail003.md).
