I have a .NET Core 2.1 project that has a BackgroundService
and I want its responsibility to just handle logging the result from a group of different tasks that can return different values. I want to group all of their output into a Task Manager class to log their output. Is it possible to have one List<Task>
that will contain all the Task
objects from these async methods?
I don't want to have multiple Task
fields for each method I want to await
on. I'd rather have them be put into a List
of some sort because there could be the possibility to have more than these three async methods I want this manager to manage.
I was thinking of doing something like:
public class MyTaskManager : BackgroundService
{
private readonly ILogger<MyTaskManager> _logger;
private APIInvoker _invoker;
public MyTaskManager (ILogger<MyTaskManager> logger, APIInvoker invoker)
{
_logger = logger;
_invoker= invoker;
}
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
List<Task<object>> tasks = new List<Task<object>>();
tasks.Add(_invoker.GetImportWarningsAsync("1"));
tasks.Add(_invoker.GetImportErrorsAsync("2"));
tasks.Add(_invoker.GetImportStatusAsync("3"));
}
Where GetImportWarningsAsync
, GetImportErrorsAsync
, GetImportStatusAsync
are defined as:
internal async Task<string> GetImportWarningsAsync(...)
internal async Task<string> GetImportErrorsAsync(...)
internal async Task<ImportResponse> GetImportLeadStatusAsync(...)
I'm fuzzy on if I can do tasks.Add(...)
if they return different types and I am adding them to a List<Task<object>>
. I don't think that is possible. How can I achieve something like that?
Ultimately, I want to run a method for each Task
in tasks
when any of them execute.
eg.
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
List<Task<object>> tasks = new List<Task<object>>();
tasks.Add(_invoker.GetImportWarningsAsync("1"));
tasks.Add(_invoker.GetImportErrorsAsync("2"));
tasks.Add(_invoker.GetImportStatusAsync("3"));
Task<object> finishedTask = await Task.WhenAny(tasks);
tasks.Remove(finishedTask);
HandleTask(finishedTask, await finishedTask);
}
private void HandleTask(Task task, object value)
{
if (value is ImportResponse)
{
_logger.LogInformation((value as ImportResponse).someProp); // Log something
}
else
{
// Any other object type will be logged here - In this case string.
_logger.LogInformation(value.ToString());
}
}