C#: Projeto Abrangente: Gerenciador de Tarefas
1. Análise de Requisitos
Vamos criar um gerenciador de tarefas de linha de comando que ofereça os seguintes recursos:
- Adicionar, excluir e concluir tarefas
- Filtrar e agrupar por prioridade
- Salvar os dados em um arquivo JSON
- Salvar de forma assíncrona sem bloquear o fluxo principal
- Tratamento abrangente de exceções
A funcionalidade é dividida em sete etapas, implementadas de forma incremental.
2. Projeto de classes: enums e modelos de dados
Primeiro, defina a enumeração de prioridades e a classe de entidade “tarefa”.
▶ Exemplo
enum Priority
{
Low,
Medium,
High
}
class Task
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Priority Priority { get; set; }
public bool IsCompleted { get; set; }
public DateTime CreatedAt { get; set; }
public Task(int id, string title, string description, Priority priority)
{
Id = id;
Title = title;
Description = description;
Priority = priority;
IsCompleted = false;
CreatedAt = DateTime.Now;
}
public override string ToString()
{
string status = IsCompleted ? "[x]" : "[ ]";
return $"{Id,-3} {status} {Priority,-6} {CreatedAt:yyyy-MM-dd} {Title}";
}
}
3. Armazenamento de coleções: TaskManager e operações CRUD
Use List<Task> para armazenar tarefas e realizar operações básicas de criação, leitura, atualização e exclusão.
▶ Exemplo
class TaskManager
{
private List<Task> tasks = new List<Task>();
private int nextId = 1;
public Task AddTask(string title, string description, Priority priority)
{
Task task = new Task(nextId++, title, description, priority);
tasks.Add(task);
return task;
}
public bool RemoveTask(int id)
{
Task task = tasks.Find(t => t.Id == id);
if (task != null)
{
tasks.Remove(task);
return true;
}
return false;
}
public bool CompleteTask(int id)
{
Task task = tasks.Find(t => t.Id == id);
if (task != null)
{
task.IsCompleted = true;
return true;
}
return false;
}
public List<Task> GetAllTasks()
{
return new List<Task>(tasks);
}
public void SortByPriority()
{
tasks.Sort((a, b) => b.Priority.CompareTo(a.Priority));
}
}
4. Persistência de arquivos: serialização e desserialização em JSON
Use System.Text.Json para salvar a lista de tarefas em um arquivo e carregá-la novamente.
▶ Exemplo
using System.Text.Json;
class TaskManager
{
private List<Task> tasks = new List<Task>();
private int nextId = 1;
private const string FilePath = "tasks.json";
private static readonly JsonSerializerOptions jsonOptions = new JsonSerializerOptions
{
WriteIndented = true
};
public string SaveToFile()
{
try
{
string json = JsonSerializer.Serialize(tasks, jsonOptions);
File.WriteAllText(FilePath, json);
return "Save succeeded.";
}
catch (Exception ex)
{
return $"Save failed: {ex.Message}";
}
}
public string LoadFromFile()
{
try
{
if (!File.Exists(FilePath))
{
return "File does not exist, skipping load.";
}
string json = File.ReadAllText(FilePath);
List<Task>? loaded = JsonSerializer.Deserialize<List<Task>>(json);
if (loaded != null)
{
tasks = loaded;
nextId = tasks.Count > 0 ? tasks.Max(t => t.Id) + 1 : 1;
}
return "Load succeeded.";
}
catch (JsonException ex)
{
return $"JSON format error: {ex.Message}";
}
catch (Exception ex)
{
return $"Load failed: {ex.Message}";
}
}
}
5. Consultas LINQ: Filtragem e agregação
Use o LINQ para implementar a filtragem por prioridade, consultar tarefas pendentes e gerar estatísticas.
▶ Exemplo
class TaskManager
{
private List<Task> tasks = new List<Task>();
public List<Task> FilterByPriority(Priority priority)
{
return tasks.Where(t => t.Priority == priority).ToList();
}
public List<Task> GetPendingTasks()
{
return tasks.Where(t => !t.IsCompleted)
.OrderByDescending(t => t.Priority)
.ToList();
}
public Dictionary<Priority, int> GetStatistics()
{
return tasks.GroupBy(t => t.Priority)
.ToDictionary(g => g.Key, g => g.Count());
}
public int GetCompletedCount()
{
return tasks.Count(t => t.IsCompleted);
}
public int GetPendingCount()
{
return tasks.Count(t => !t.IsCompleted);
}
}
Sample statistics output:
High: 2, Medium: 3, Low: 1
Completed: 1, Pending: 5
6. Salvamento assíncrono de arquivos
Use async/await para implementar operações de gravação em arquivos sem bloqueio.
▶ Exemplo
class TaskManager
{
private List<Task> tasks = new List<Task>();
private const string FilePath = "tasks.json";
private static readonly JsonSerializerOptions jsonOptions = new JsonSerializerOptions
{
WriteIndented = true
};
public async Task````<string>```` SaveToFileAsync()
{
try
{
string json = JsonSerializer.Serialize(tasks, jsonOptions);
await File.WriteAllTextAsync(FilePath, json);
return "Async save succeeded.";
}
catch (UnauthorizedAccessException ex)
{
return $"File access denied: {ex.Message}";
}
catch (IOException ex)
{
return $"IO error: {ex.Message}";
}
catch (Exception ex)
{
return $"Async save failed: {ex.Message}";
}
}
public async Task````<string>```` LoadFromFileAsync()
{
try
{
if (!File.Exists(FilePath))
{
return "File does not exist, skipping load.";
}
string json = await File.ReadAllTextAsync(FilePath);
List<Task>? loaded = JsonSerializer.Deserialize<List<Task>>(json);
if (loaded != null)
{
tasks = loaded;
nextId = tasks.Count > 0 ? tasks.Max(t => t.Id) + 1 : 1;
}
return "Async load succeeded.";
}
catch (JsonException ex)
{
return $"JSON format error: {ex.Message}";
}
catch (Exception ex)
{
return $"Async load failed: {ex.Message}";
}
}
}
7. Interface interativa de linha de comando
Use uma instrução switch para criar um loop de menu na linha de comando.
▶ Exemplo
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
TaskManager manager = new TaskManager();
string loadResult = await manager.LoadFromFileAsync();
Console.WriteLine(loadResult);
while (true)
{
Console.WriteLine("\n===== Task Manager =====");
Console.WriteLine("1. Add task");
Console.WriteLine("2. Delete task");
Console.WriteLine("3. Complete task");
Console.WriteLine("4. List all tasks");
Console.WriteLine("5. Filter by priority");
Console.WriteLine("6. View statistics");
Console.WriteLine("7. Save to file");
Console.WriteLine("0. Exit");
Console.Write("Select: ");
string? input = Console.ReadLine();
switch (input)
{
case "1":
Console.Write("Title: ");
string? title = Console.ReadLine() ?? "";
Console.Write("Description: ");
string? desc = Console.ReadLine() ?? "";
Console.Write("Priority (Low/Medium/High): ");
string? priStr = Console.ReadLine();
if (Enum.TryParse<Priority>(priStr, true, out Priority pri))
{
Task added = manager.AddTask(title, desc, pri);
Console.WriteLine($"Added: {added}");
}
else
{
Console.WriteLine("Invalid priority.");
}
break;
case "2":
Console.Write("Task ID: ");
if (int.TryParse(Console.ReadLine(), out int delId))
{
Console.WriteLine(manager.RemoveTask(delId) ? "Deleted." : "Not found.");
}
break;
case "3":
Console.Write("Task ID: ");
if (int.TryParse(Console.ReadLine(), out int compId))
{
Console.WriteLine(manager.CompleteTask(compId) ? "Completed." : "Not found.");
}
break;
case "4":
manager.SortByPriority();
foreach (Task t in manager.GetAllTasks())
{
Console.WriteLine(t);
}
break;
case "5":
Console.Write("Priority (Low/Medium/High): ");
if (Enum.TryParse<Priority>(Console.ReadLine(), true, out Priority filterPri))
{
foreach (Task t in manager.FilterByPriority(filterPri))
{
Console.WriteLine(t);
}
}
break;
case "6":
Dictionary<Priority, int> stats = manager.GetStatistics();
foreach (var kv in stats)
{
Console.WriteLine($"{kv.Key}: {kv.Value}");
}
Console.WriteLine($"Completed: {manager.GetCompletedCount()}, Pending: {manager.GetPendingCount()}");
break;
case "7":
string saveResult = await manager.SaveToFileAsync();
Console.WriteLine(saveResult);
break;
case "0":
string finalSave = await manager.SaveToFileAsync();
Console.WriteLine(finalSave);
Console.WriteLine("Goodbye!");
return;
default:
Console.WriteLine("Invalid selection.");
break;
}
}
}
}
===== Task Manager =====
1. Add task
2. Delete task
3. Complete task
4. List all tasks
5. Filter by priority
6. View statistics
7. Save to file
0. Exit
Select: 1
Title: Learn C#
Description: Complete lesson 36
Priority (Low/Medium/High): High
Added: 1 [ ] High 2026-06-28 Learn C#
8. Organização da estrutura do projeto
Use namespaces e using para organizar o código, colocando diferentes responsabilidades em arquivos separados.
▶ Exemplo
Estrutura dos arquivos do projeto:
TaskManagerApp/
├── Models/
│ ├── Priority.cs
│ └── Task.cs
├── Services/
│ └── TaskManager.cs
└── Program.cs
Priority.cs:
namespace TaskManagerApp.Models
{
public enum Priority
{
Low,
Medium,
High
}
}
Task.cs:
using System;
namespace TaskManagerApp.Models
{
public class Task
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Priority Priority { get; set; }
public bool IsCompleted { get; set; }
public DateTime CreatedAt { get; set; }
public Task(int id, string title, string description, Priority priority)
{
Id = id;
Title = title;
Description = description;
Priority = priority;
IsCompleted = false;
CreatedAt = DateTime.Now;
}
public override string ToString()
{
string status = IsCompleted ? "[x]" : "[ ]";
return $"{Id,-3} {status} {Priority,-6} {CreatedAt:yyyy-MM-dd} {Title}";
}
}
}
TaskManager.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using TaskManagerApp.Models;
namespace TaskManagerApp.Services
{
public class TaskManager
{
private List<Models.Task> tasks = new List<Models.Task>();
private int nextId = 1;
private const string FilePath = "tasks.json";
private static readonly JsonSerializerOptions jsonOptions = new JsonSerializerOptions
{
WriteIndented = true
};
public Models.Task AddTask(string title, string description, Priority priority)
{
Models.Task task = new Models.Task(nextId++, title, description, priority);
tasks.Add(task);
return task;
}
public bool RemoveTask(int id)
{
Models.Task? task = tasks.Find(t => t.Id == id);
if (task != null)
{
tasks.Remove(task);
return true;
}
return false;
}
public bool CompleteTask(int id)
{
Models.Task? task = tasks.Find(t => t.Id == id);
if (task != null)
{
task.IsCompleted = true;
return true;
}
return false;
}
public List<Models.Task> GetAllTasks()
{
return new List<Models.Task>(tasks);
}
public void SortByPriority()
{
tasks.Sort((a, b) => b.Priority.CompareTo(a.Priority));
}
public List<Models.Task> FilterByPriority(Priority priority)
{
return tasks.Where(t => t.Priority == priority).ToList();
}
public List<Models.Task> GetPendingTasks()
{
return tasks.Where(t => !t.IsCompleted)
.OrderByDescending(t => t.Priority)
.ToList();
}
public Dictionary<Priority, int> GetStatistics()
{
return tasks.GroupBy(t => t.Priority)
.ToDictionary(g => g.Key, g => g.Count());
}
public int GetCompletedCount()
{
return tasks.Count(t => t.IsCompleted);
}
public int GetPendingCount()
{
return tasks.Count(t => !t.IsCompleted);
}
public async Task````<string>```` SaveToFileAsync()
{
try
{
string json = JsonSerializer.Serialize(tasks, jsonOptions);
await File.WriteAllTextAsync(FilePath, json);
return "Save succeeded.";
}
catch (UnauthorizedAccessException ex)
{
return $"Access denied: {ex.Message}";
}
catch (IOException ex)
{
return $"IO error: {ex.Message}";
}
catch (Exception ex)
{
return $"Save failed: {ex.Message}";
}
}
public async Task````<string>```` LoadFromFileAsync()
{
try
{
if (!File.Exists(FilePath))
{
return "File does not exist, skipping load.";
}
string json = await File.ReadAllTextAsync(FilePath);
List<Models.Task>? loaded = JsonSerializer.Deserialize<List<Models.Task>>(json);
if (loaded != null)
{
tasks = loaded;
nextId = tasks.Count > 0 ? tasks.Max(t => t.Id) + 1 : 1;
}
return "Load succeeded.";
}
catch (JsonException ex)
{
return $"JSON format error: {ex.Message}";
}
catch (Exception ex)
{
return $"Load failed: {ex.Message}";
}
}
}
}
Program.cs:
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using TaskManagerApp.Models;
using TaskManagerApp.Services;
namespace TaskManagerApp
{
class Program
{
static async Task Main()
{
TaskManager manager = new TaskManager();
string loadResult = await manager.LoadFromFileAsync();
Console.WriteLine(loadResult);
while (true)
{
Console.WriteLine("\n===== Task Manager =====");
Console.WriteLine("1. Add task");
Console.WriteLine("2. Delete task");
Console.WriteLine("3. Complete task");
Console.WriteLine("4. List all tasks");
Console.WriteLine("5. Filter by priority");
Console.WriteLine("6. View statistics");
Console.WriteLine("7. Save to file");
Console.WriteLine("0. Exit");
Console.Write("Select: ");
string? input = Console.ReadLine();
switch (input)
{
case "1":
Console.Write("Title: ");
string? title = Console.ReadLine() ?? "";
Console.Write("Description: ");
string? desc = Console.ReadLine() ?? "";
Console.Write("Priority (Low/Medium/High): ");
string? priStr = Console.ReadLine();
if (Enum.TryParse<Priority>(priStr, true, out Priority pri))
{
Models.Task added = manager.AddTask(title, desc, pri);
Console.WriteLine($"Added: {added}");
}
else
{
Console.WriteLine("Invalid priority.");
}
break;
case "2":
Console.Write("Task ID: ");
if (int.TryParse(Console.ReadLine(), out int delId))
{
Console.WriteLine(manager.RemoveTask(delId) ? "Deleted." : "Not found.");
}
break;
case "3":
Console.Write("Task ID: ");
if (int.TryParse(Console.ReadLine(), out int compId))
{
Console.WriteLine(manager.CompleteTask(compId) ? "Completed." : "Not found.");
}
break;
case "4":
manager.SortByPriority();
foreach (Models.Task t in manager.GetAllTasks())
{
Console.WriteLine(t);
}
break;
case "5":
Console.Write("Priority (Low/Medium/High): ");
if (Enum.TryParse<Priority>(Console.ReadLine(), true, out Priority filterPri))
{
foreach (Models.Task t in manager.FilterByPriority(filterPri))
{
Console.WriteLine(t);
}
}
break;
case "6":
Dictionary<Priority, int> stats = manager.GetStatistics();
foreach (var kv in stats)
{
Console.WriteLine($"{kv.Key}: {kv.Value}");
}
Console.WriteLine($"Completed: {manager.GetCompletedCount()}, Pending: {manager.GetPendingCount()}");
break;
case "7":
string saveResult = await manager.SaveToFileAsync();
Console.WriteLine(saveResult);
break;
case "0":
string finalSave = await manager.SaveToFileAsync();
Console.WriteLine(finalSave);
Console.WriteLine("Goodbye!");
return;
default:
Console.WriteLine("Invalid selection.");
break;
}
}
}
}
}
9. Versão completa em um único arquivo
Junte todo o código em um único arquivo compilável para testes rápidos.
▶ Exemplo
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
enum Priority
{
Low,
Medium,
High
}
class Task
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public Priority Priority { get; set; }
public bool IsCompleted { get; set; }
public DateTime CreatedAt { get; set; }
public Task(int id, string title, string description, Priority priority)
{
Id = id;
Title = title;
Description = description;
Priority = priority;
IsCompleted = false;
CreatedAt = DateTime.Now;
}
public override string ToString()
{
string status = IsCompleted ? "[x]" : "[ ]";
return $"{Id,-3} {status} {Priority,-6} {CreatedAt:yyyy-MM-dd} {Title}";
}
}
class TaskManager
{
private List<Task> tasks = new List<Task>();
private int nextId = 1;
private const string FilePath = "tasks.json";
private static readonly JsonSerializerOptions jsonOptions = new JsonSerializerOptions
{
WriteIndented = true
};
public Task AddTask(string title, string description, Priority priority)
{
Task task = new Task(nextId++, title, description, priority);
tasks.Add(task);
return task;
}
public bool RemoveTask(int id)
{
Task? task = tasks.Find(t => t.Id == id);
if (task != null)
{
tasks.Remove(task);
return true;
}
return false;
}
public bool CompleteTask(int id)
{
Task? task = tasks.Find(t => t.Id == id);
if (task != null)
{
task.IsCompleted = true;
return true;
}
return false;
}
public List<Task> GetAllTasks()
{
return new List<Task>(tasks);
}
public void SortByPriority()
{
tasks.Sort((a, b) => b.Priority.CompareTo(a.Priority));
}
public List<Task> FilterByPriority(Priority priority)
{
return tasks.Where(t => t.Priority == priority).ToList();
}
public List<Task> GetPendingTasks()
{
return tasks.Where(t => !t.IsCompleted)
.OrderByDescending(t => t.Priority)
.ToList();
}
public Dictionary<Priority, int> GetStatistics()
{
return tasks.GroupBy(t => t.Priority)
.ToDictionary(g => g.Key, g => g.Count());
}
public int GetCompletedCount()
{
return tasks.Count(t => t.IsCompleted);
}
public int GetPendingCount()
{
return tasks.Count(t => !t.IsCompleted);
}
public async Task````<string>```` SaveToFileAsync()
{
try
{
string json = JsonSerializer.Serialize(tasks, jsonOptions);
await File.WriteAllTextAsync(FilePath, json);
return "Save succeeded.";
}
catch (UnauthorizedAccessException ex)
{
return $"Access denied: {ex.Message}";
}
catch (IOException ex)
{
return $"IO error: {ex.Message}";
}
catch (Exception ex)
{
return $"Save failed: {ex.Message}";
}
}
public async Task````<string>```` LoadFromFileAsync()
{
try
{
if (!File.Exists(FilePath))
{
return "File does not exist, skipping load.";
}
string json = await File.ReadAllTextAsync(FilePath);
List<Task>? loaded = JsonSerializer.Deserialize<List<Task>>(json);
if (loaded != null)
{
tasks = loaded;
nextId = tasks.Count > 0 ? tasks.Max(t => t.Id) + 1 : 1;
}
return "Load succeeded.";
}
catch (JsonException ex)
{
return $"JSON format error: {ex.Message}";
}
catch (Exception ex)
{
return $"Load failed: {ex.Message}";
}
}
}
class Program
{
static async Task Main()
{
TaskManager manager = new TaskManager();
string loadResult = await manager.LoadFromFileAsync();
Console.WriteLine(loadResult);
while (true)
{
Console.WriteLine("\n===== Task Manager =====");
Console.WriteLine("1. Add task");
Console.WriteLine("2. Delete task");
Console.WriteLine("3. Complete task");
Console.WriteLine("4. List all tasks");
Console.WriteLine("5. Filter by priority");
Console.WriteLine("6. View statistics");
Console.WriteLine("7. Save to file");
Console.WriteLine("0. Exit");
Console.Write("Select: ");
string? input = Console.ReadLine();
switch (input)
{
case "1":
Console.Write("Title: ");
string? title = Console.ReadLine() ?? "";
Console.Write("Description: ");
string? desc = Console.ReadLine() ?? "";
Console.Write("Priority (Low/Medium/High): ");
string? priStr = Console.ReadLine();
if (Enum.TryParse<Priority>(priStr, true, out Priority pri))
{
Task added = manager.AddTask(title, desc, pri);
Console.WriteLine($"Added: {added}");
}
else
{
Console.WriteLine("Invalid priority.");
}
break;
case "2":
Console.Write("Task ID: ");
if (int.TryParse(Console.ReadLine(), out int delId))
{
Console.WriteLine(manager.RemoveTask(delId) ? "Deleted." : "Not found.");
}
break;
case "3":
Console.Write("Task ID: ");
if (int.TryParse(Console.ReadLine(), out int compId))
{
Console.WriteLine(manager.CompleteTask(compId) ? "Completed." : "Not found.");
}
break;
case "4":
manager.SortByPriority();
foreach (Task t in manager.GetAllTasks())
{
Console.WriteLine(t);
}
break;
case "5":
Console.Write("Priority (Low/Medium/High): ");
if (Enum.TryParse<Priority>(Console.ReadLine(), true, out Priority filterPri))
{
foreach (Task t in manager.FilterByPriority(filterPri))
{
Console.WriteLine(t);
}
}
break;
case "6":
Dictionary<Priority, int> stats = manager.GetStatistics();
foreach (var kv in stats)
{
Console.WriteLine($"{kv.Key}: {kv.Value}");
}
Console.WriteLine($"Completed: {manager.GetCompletedCount()}, Pending: {manager.GetPendingCount()}");
break;
case "7":
string saveResult = await manager.SaveToFileAsync();
Console.WriteLine(saveResult);
break;
case "0":
string finalSave = await manager.SaveToFileAsync();
Console.WriteLine(finalSave);
Console.WriteLine("Goodbye!");
return;
default:
Console.WriteLine("Invalid selection.");
break;
}
}
}
}
Load succeeded.
===== Task Manager =====
1. Add task
2. Delete task
3. Complete task
4. List all tasks
5. Filter by priority
6. View statistics
7. Save to file
0. Exit
Select: 1
Title: Learn C#
Description: Complete lesson 36
Priority (Low/Medium/High): High
Added: 1 [ ] High 2026-06-28 Learn C#
Select: 1
Title: Write documentation
Description: Organize project docs
Priority (Low/Medium/High): Medium
Added: 2 [ ] Medium 2026-06-28 Write documentation
Select: 3
Task ID: 2
Completed.
Select: 4
2 [x] Medium 2026-06-28 Write documentation
1 [ ] High 2026-06-28 Learn C#
Select: 6
High: 1
Medium: 1
Completed: 1, Pending: 1
Select: 0
Save succeeded.
Goodbye!
❓ Perguntas Frequentes
P: Por que a serialização exige um construtor sem parâmetros? R: O System.Text.Json exige um por padrão; você pode contornar isso personalizando um conversor por meio do JsonSerializerOptions.
P: O que acontece quando o método List.Find não encontra um elemento? R: O método Find retorna null sem lançar uma exceção; sempre verifique se o resultado é null antes de usá-lo.
P: O que acontece se um método assíncrono não tiver um
await? R: A tarefa passa a ser do tipo “fire and forget” — as exceções não serão capturadas, o que pode causar perda de dados.
P: O que o Enum.TryParse retorna em caso de falha? R: Ele retorna false, o parâmetro de saída mantém seu valor padrão e nenhuma exceção é lançada.
📖 Resumo
- Os tipos de enumeração definem conjuntos finitos de estados, melhorando a legibilidade do código
- As classes de entidade encapsulam dados e comportamento; o método ToString fornece uma saída formatada
- A lista
<T>, combinada com as funções Find, Sort e Where, implementa operações de coleção - O System.Text.Json oferece serialização e desserialização leves
- Os operadores Where, OrderBy e GroupBy do LINQ permitem consultas declarativas
- async/await implementa E/S de arquivos sem bloqueio
- O try-catch captura primeiro exceções específicas e, em seguida, recorre à Exception
- as instruções
switchcriam loops de menu na linha de comando - namespace e como organizar estruturas de projetos com vários arquivos
📝 Exercícios
- Adicione uma propriedade DueDate à classe Task e implemente um recurso para “exibir tarefas vencidas”
- Adicione um método EditTask ao TaskManager que permita modificar o título e a descrição
- Altere o formato de salvamento de JSON para CSV, implementando sua própria lógica de serialização
- Adicionar a classificação por data de criação e a pesquisa por título
- Implementar um modo de argumentos de linha de comando: o programa executa uma operação por meio dos argumentos fornecidos na inicialização e, em seguida, encerra a execução