hel*_*ker 1 c# linq asynchronous async-await
我想创建一个等待任务的集合,以便我可以一起启动它们并在完成时异步处理每个任务的结果.
我有这个代码,并有一个编译错误:
> cannot assign void to an implicitly-typed variable
如果我理解得很好,返回的任务Select没有返回类型,即使委托传递了返回ColetaIsisViewModel,我会想:
public MainViewModel()
{
Task.Run(LoadItems);
}
async Task LoadItems()
{
IEnumerable<Task> tasks = Directory.GetDirectories(somePath)
.Select(dir => new Task(() =>
new ItemViewModel(new ItemSerializer().Deserialize(dir))));
foreach (var task in tasks)
{
var result = await task; // <-- here I get the compilation error
DoSomething(result);
}
}
Run Code Online (Sandbox Code Playgroud)
你不应该使用Task构造函数.
由于您正在调用同步代码(Deserialize),因此您可以使用Task.Run:
async Task LoadItems()
{
var tasks = Directory.GetDirectories(somePath)
.Select(dir => Task.Run(() =>
new ItemViewModel(new ItemSerializer().Deserialize(dir))));
foreach (var task in tasks)
{
var result = await task;
DoSomething(result);
}
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用Parallel或并行LINQ:
void LoadItems()
{
var vms = Directory.GetDirectories(somePath)
.AsParallel().Select(dir =>
new ItemViewModel(new ItemSerializer().Deserialize(dir)))
.ToList();
foreach (var vm in vms)
{
DoSomething(vm);
}
}
Run Code Online (Sandbox Code Playgroud)
或者,如果你创建Deserialize一个真正的async方法,那么你可以使它全部异步:
async Task LoadItems()
{
var tasks = Directory.GetDirectories(somePath)
.Select(async dir =>
new ItemViewModel(await new ItemSerializer().DeserializeAsync(dir))));
foreach (var task in tasks)
{
var result = await task;
DoSomething(result);
}
}
Run Code Online (Sandbox Code Playgroud)
另外,我建议你不要在构造函数中使用fire-and-forget.异步构造函数有更好的模式.