C# Can';在使用任务构造函数时,不要使用结果启动任务
我有一大堆任务,我希望能够按顺序运行。问题是,它们涉及大量的磁盘读取,我需要在使用每一个磁盘之间进行一些磁盘读取/写入,因此我希望能够创建一系列任务来从磁盘读取(并返回结果),但在准备好之前不启动它们 因此,我无法使用C# Can';在使用任务构造函数时,不要使用结果启动任务,c#,windows-runtime,windows-phone,windows-store-apps,async-await,C#,Windows Runtime,Windows Phone,Windows Store Apps,Async Await,我有一大堆任务,我希望能够按顺序运行。问题是,它们涉及大量的磁盘读取,我需要在使用每一个磁盘之间进行一些磁盘读取/写入,因此我希望能够创建一系列任务来从磁盘读取(并返回结果),但在准备好之前不启动它们 因此,我无法使用Task.Run或Task.Factory.StartNew。据我所知,这就是任务构造函数的用途 例: 有没有办法做到这一点?当前task.Start()引发异常:System.InvalidOperationException:其他信息:不能对承诺式任务调用Start。 编辑:应
Task.Run
或Task.Factory.StartNew
。据我所知,这就是任务
构造函数的用途
例:
有没有办法做到这一点?当前task.Start()引发异常:System.InvalidOperationException:其他信息:不能对承诺式任务调用Start。
编辑:应该注意的是,它现在的样子有些奇怪。这是因为在每个步骤中,比如读取文件,我都会在返回数据之前对数据进行一些额外的逻辑处理。这应该不会影响代码,只要我可以在任务构造函数方法中进行异步调用
Edit2:似乎有人想让我更清楚地回答我的问题
有没有一种方法可以创建一个带有返回值的任务,但不启动它(可能使用
任务构造函数
),这样我就可以启动它并在其他时间等待该值。目前我收到了上面包含的异常。我似乎已经解决了。基于
似乎我需要保留外部任务和调用任务的副本。单独开始,然后我可以按预期返回未包装的任务。例如:
public async Task<IEnumberable<Task<byte[]>>> ReadAllFiles()
{
var folder = await ApplicationData.Current.LocalFolder;
var files = await folder.GetFilesAsync();
var fileTasks = files.Select(
file => {
var wrappedTask = new Task<Task<byte[]>>(
async () => {
return (await FileIO.ReadBufferAsync(file)).ToArray();
});
var unwrappedTask = wrappedTask.Unwrap();
wrappedTask.Start();
return unwrappedTask;
});
return fileTasks;
}
public异步任务ReadAllFiles()
{
var folder=wait ApplicationData.Current.LocalFolder;
var files=await folder.getfileasync();
var fileTasks=文件。选择(
文件=>{
var wrappedTask=新任务(
异步()=>{
return(wait FileIO.ReadBufferAsync(file)).ToArray();
});
var unwrappedTask=wrappedTask.Unwrap();
wrappedTask.Start();
返回未包装任务;
});
返回文件任务;
}
这将确保展开已完成,并计划内部任务(但不启动它)。
任务。运行,任务。工厂。开始新建和任务。任务都适用于CPU限制的任务。您的任务是I/O绑定的
有没有一种方法,我可以创建一个返回值的任务,但不能启动它。。。以便我可以启动它,并在另一个时间等待值
当然;实际上,您需要的是一个具有异步
兼容签名的委托。在本例中,aFunc
。我有更多与异步
兼容的委托的示例
因此,您的示例可以是:
public async Task<IEnumberable<Task<byte[]>>> ReadAllFiles()
{
var folder = await ApplicationData.Current.LocalFolder;
var files = await folder.GetFilesAsync();
var fileReaders = files.Select(file => new Func<Task<byte[]>>(
async () => await FileIO.ReadBufferAsync(file)).ToArray()));
return fileReaders;
}
var readers = await ReadAllFiles();
foreach(var func in readers)
{
var bytes = await func();
// Do other stuff
}
public异步任务ReadAllFiles()
{
var folder=wait ApplicationData.Current.LocalFolder;
var files=await folder.getfileasync();
var fileReaders=files.Select(file=>newfunc(
async()=>等待FileIO.ReadBufferAsync(file)).ToArray();
返回文件读取器;
}
var readers=wait ReadAllFiles();
foreach(读卡器中的var func)
{
var bytes=wait func();
//做其他事情
}
首先为什么要在此处使用Start()
?因此,当您使用Task.Run
或Task.Factory.StartNew
时,它会自动启动它创建的任务。使用task
构造函数创建任务时,它不会启动它。这意味着您必须调用Task.Start()
来启动任务,否则如果您等待它,它将永远不会返回。是的,但是您的ReadAllFiles()
返回一个延迟序列,因此即使您使用Task.Run()
,只有在我没有考虑的foreach
中迭代任务时,任务才会启动。我试试看。因此,即使它通过Task.Run返回任务,在枚举之前它实际上不会调用Select lambda?确切地说,LINQ通常就是这样工作的。
public async Task<IEnumberable<Task<byte[]>>> ReadAllFiles()
{
var folder = await ApplicationData.Current.LocalFolder;
var files = await folder.GetFilesAsync();
var fileTasks = files.Select(
file => {
var wrappedTask = new Task<Task<byte[]>>(
async () => {
return (await FileIO.ReadBufferAsync(file)).ToArray();
});
var unwrappedTask = wrappedTask.Unwrap();
wrappedTask.Start();
return unwrappedTask;
});
return fileTasks;
}
public async Task<IEnumberable<Task<byte[]>>> ReadAllFiles()
{
var folder = await ApplicationData.Current.LocalFolder;
var files = await folder.GetFilesAsync();
var fileReaders = files.Select(file => new Func<Task<byte[]>>(
async () => await FileIO.ReadBufferAsync(file)).ToArray()));
return fileReaders;
}
var readers = await ReadAllFiles();
foreach(var func in readers)
{
var bytes = await func();
// Do other stuff
}