У меня есть набор задач, которые я хочу выполнить в порядке. Дело в том, что они связаны с большим количеством чтения диска, и мне нужно будет делать чтение/запись на диске между ними, поэтому я хотел бы иметь возможность создавать кучу задач для чтения с диска (и возвращать результат), но не запускать их, пока я не буду готов.Не удается запустить задачу с результатом при использовании конструктора задач
Из-за этого я не могу использовать Task.Run
или Task.Factory.StartNew
. Я понимаю, что для этого был конструктор Task
.
Ex:
public async Task<IEnumberable<Task<byte[]>>> ReadAllFiles()
{
var folder = await ApplicationData.Current.LocalFolder;
var files = await folder.GetFilesAsync();
var fileTasks = files.Select(
file => new Task<Task<byte[]>>(
async() => {
return (await FileIO.ReadBufferAsync(file)).ToArray();
}).Unwrap());
return fileTasks;
}
Тогда в моем вызывающем методе я могу пойти:
var readTasks = await ReadAllFiles();
foreach(var task in readTasks)
{
task.Start(); // Throws exception
var bytes = await task; // If the previous line is commented out, does not return
// Do other stuff
}
Есть ли способ сделать это? Прямо сейчас task.Start() выдает исключение: System.InvalidOperationException: Additional information: Start may not be called on a promise-style task.
.
Редактировать: Следует отметить, что в настоящее время есть некоторые странности. Это связано с тем, что на каждом этапе, таком как чтение файла, я делаю дополнительную логическую обработку данных перед их возвратом. Это не должно влиять на код, если я могу выполнять асинхронные вызовы в методе конструктора задач.
Edit2: Кажется, мне хотелось бы, чтобы я был более ясен с тем, что я прошу.
Есть ли способ создать задачу с возвращаемым значением, но не запускать ее (вероятно, используя Task<TResult> constructor
), чтобы я мог начать ее и ждать значения в другое время. В настоящее время я получаю исключение, включенное выше.
Почему вы пытаетесь использовать 'Start()' здесь в первую очередь? – svick
Итак, когда вы используете 'Task.Run' или' Task.Factory.StartNew', он автоматически запускает задание, которое он создает. Когда вы создаете задачу с помощью конструктора 'Task', она не запускает ее.Это означает, что вы должны вызвать 'Task.Start()' для запуска задачи, иначе, если вы ее ждете, она никогда не вернется. –
Да, но ваш 'ReadAllFiles()' возвращает ленивую последовательность, поэтому даже если вы использовали 'Task.Run()', 'Task' запускался бы только тогда, когда вы перебираете их в своем 'foreach'. – svick