I have a bunch of tasks that I want to be able to run in order. The thing is, they involve a lot of disk reading and I will need to do some disk reading/writing in between using each one, so I'd like to be able to create a bunch of tasks for reading from the disk (and returning the result), but not starting them until I'm ready to.
Because of this, I can't use Task.Run
or Task.Factory.StartNew
. It is my understanding that this is what the Task
constructor was for.
Ex:
public async Task<IEnumerable<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;
}
Then, in my calling method I can go:
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
}
Is there any way to do this? Right now task.Start() throws an exception: System.InvalidOperationException: Additional information: Start may not be called on a promise-style task.
.
Edit: It should be noted that there are some weirdnesses with how it looks currently. This is because in each step such as reading the file, I'm doing some additional logic processing on the data before returning it. This should not affect the code, so long as I can make asynchronous calls in the Task constructor method.
Edit2: It seems someone would like me to be clearer with what I am asking.
Is there a way that I can create a task with a return value, but not start it (likely using the Task<TResult> constructor
) so that I may start it and await the value at another time. Currently I am receiving the exception included above.