Одна задача, ожидает выполнение другой задачи, как только возвращаем null
из ожидаемой задачи, происходит прерывание выполнения другой.
Как вернуть null
из Task<T>
, при этом не прервать выполнение родительского Task<T>
, и продолжить выполнение в штатном режиме?
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
public class TaskOperation
{
public bool GetNUll { get; set; }
}
public class SomeTasks
{
public async Task<ObservableCollection<TaskOperation>> GetAllTasks()
{
ObservableCollection<TaskOperation> taskOperations = new ObservableCollection<TaskOperation>();
for (int i = 0; i < 120; i++)
{
taskOperations.Add(new TaskOperation { GetNUll = i % 2 == 0 });
}
int t = 0;
foreach (var taskOperation in taskOperations)
{
if (!(await GetTask(taskOperation)).GetNUll)
{
Console.WriteLine($"{t}");
}
}
return taskOperations;
}
public Task<TaskOperation> GetTask(TaskOperation operation)
{
return operation.GetNUll ? null : Task.Factory.StartNew(() => operation);
}
}
static void Main(string[] args)
{
SomeTasks someTasks = new SomeTasks();
Task.Run(async () => await someTasks.GetAllTasks());
Console.Read();
}
}
}
Данная задача будет прервана на первой же итерации цикла.
Поглядим на код:
async Task ParentTask()
{
await ChildTask(); // ожидаем Task<T>, всё хорошо
await ChildTaskNull(); // await null - ошибка
}
Task<string> ChildTask()
{
return Task.FromResult<string>(null);
}
Task<string> ChildTaskNull()
{
return null;
}
Смотрим что тут происходит:
У нас есть родительская функция и 2 дочерние. В родительской мы сначала вызываем ChildTask()
, который возвращает экземпляр Task<string>
, который мы можем ожидать. Потому await ChildTask();
работает нормально.
Далее, ChildTaskNull()
возвращает NULL, но NULL - это не экземпляр задачи, это просто пустой указатель. потому await ChildTaskNull();
превращается в await null
, что и порождает исключение в родительской задаче.
Как вывод, если ваша функция НЕ асинхронная и просто возвращает Task<T>
, и вам надо вернуть null как результат операции, используйте return Task.FromResult<T>(null)
или Task.FromResult((T)null)
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Как отправить в C# hex а не string на tcp? Использую для проверки програму-клиент-сервер и если конвертировать string в байты то эта программа получит...