У меня есть метод async после завершения которого я хочу запустить другой метод. Это отлично работает, если я просто вызываю метод и добавляю .ContinueWith()Создать хорошую задачу холода
Однако у меня есть новое требование, которое должно только запускать задачу, если я могу добавить ее в параллельный словарь.
Я хотел бы построить задачу, попытаться добавить его, а затем запустить задачу
Тем не менее, кажется, что Task.Start() немедленно завершает задание, вызывающее действие продолжать работать и все ждет .. не ждать.
может кто-нибудь объяснить, почему это происходит, и правильный путь для достижения моей цели?
namespace UnitTestProject2
{
[TestClass]
public class taskProblem
{
[TestMethod]
public void Test()
{
CancellationTokenSource cancel = new CancellationTokenSource();
ConcurrentDictionary<Guid, Task> tasks = new ConcurrentDictionary<Guid,Task>();
Guid id = Guid.NewGuid();
Task t = new Task(async() => await Get(), cancel.Token);
t.ContinueWith(Complete);
if (tasks.TryAdd(id, t))
{
t.Start();
}
else
{
//another thread is stopping stuff dont start new tasks
}
t.Wait(); //expected to wait for the get function to complete
Console.WriteLine("end test");
}
public async Task Get()
{
Console.WriteLine("start task");
await Task.Delay(10000);
Console.WriteLine("end task");
}
public void Complete(Task t)
{
Console.WriteLine("Complete");
}
}
}
выход:
start task
end test
Complete
ожидается выход:
start task
end task
Complete
end test
Update: Оказывается, нет никакого способа, чтобы создать новую задачу, которая не будет немедленно начать или полностью немедленно на Task.Start?
В чем проблема, которую вы пытаетесь решить?Требование не имеет смысла и обертывания Задачи, которые два уровня глубоко не помогают. Существует * никогда * хорошая причина для создания холодных задач и вызова 'Start'. Более того, нет причин для переноса «Get», который уже возвращает запущенную задачу внутри другой. Просто напишите 'Task t = Get();'. Что касается требования, это не имеет смысла. Вы всегда можете добавить новый элемент в параллельный словарь, поскольку на самом деле вы создаете для него новый ключ Guid. –
Похоже, вы передаете делегат async в конструктор 'Task', который не будет ждать завершения задачи, возвращаемой из' Get'. Почему вы пытаетесь связать вызов 'Get' в другой задаче? – Lee
настоящее приложение отправляет push-уведомления из очереди и имеет метод Stop() (вызванный из другого потока), чтобы остановить запуск новых задач. В этом случае мне нужна незапущенная задача, поэтому я могу добавить ее в параллельный словарь по потоковому безопасному пути. очевидно, есть другие способы сделать это, которые я буду вынужден использовать, если я не могу это понять. – Ewan