Ra'*_*raj 7 c# async-await uwp
我正在构建一个 UWP 应用程序,它从文件夹中获取文件列表,对它们进行一些处理,然后删除这些文件。
这工作正常:
List<StorageFile> files;
public MainPage()
{
this.InitializeComponent();
files = new List<StorageFile>();
}
private async Task<List<StorageFile>> GetFiles(StorageFolder folder)
{
var items = await folder.GetItemsAsync();
foreach (var item in items)
{
if (item.GetType() == typeof(StorageFile))
files.Add(item);
else
await GetFiles(item as StorageFolder);
}
return files;
}
private async void GetFilesBtn_Click(object sender, RoutedEventArgs e)
{
// opening folder picker, then selecting a folder
var files = await GetFiles(folder);
// process files
ProcessFiles(files);
// dispose
DisposeFiles(files);
}
Run Code Online (Sandbox Code Playgroud)
然而,当处理大量文件时,内存消耗非常高(显然)。
因此,我想到的是使用yield return file和处理每个文件,然后一旦完成该文件,我就可以处理它,并开始处理下一个文件,依此类推。
我试图做的是:
public async Task<IEnumerable<StorageFile>> GetFiles(StorageFolder folder)
{
var items = await folder.GetItemsAsync();
foreach (var item in items)
{
if (item.GetType() == typeof(StorageFile))
yield return item;
else
await GetFiles(item as StorageFolder);
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
foreach (var file in GetFiles(folder))
{
// process file
ProcessFile(file);
// dispose
DisposeFile(file);
}
Run Code Online (Sandbox Code Playgroud)
这样做时我得到:
“GetFiles(StorageFolder)”的主体不能是迭代器块,因为任务 IEnumerable StorageFile 不是迭代器接口类型。
我以前从未使用过yield return,所以我不确定如何实现这一点。
Cra*_*own 10
从 C# 8 开始,现在可以使用IAsyncEnumerable.
您只需将返回类型从Task<IEnumerable<StorageFile>>to更改为,然后使用而不是IAsyncEnumerable<StorageFile>调用该方法。await foreachforeach
所以你的例子现在看起来像这样:
public async IAsyncEnumerable<StorageFile> GetFiles(StorageFolder folder)
{
var items = await folder.GetItemsAsync();
foreach (var item in items)
{
if (item.GetType() == typeof(StorageFile))
yield return item;
else
await foreach (var item2 in GetFiles(item as StorageFolder))
yield return item2;
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
await foreach (var file in GetFiles(folder))
{
// process file
ProcessFile(file);
// dispose
DisposeFile(file);
}
Run Code Online (Sandbox Code Playgroud)
moi*_*ien -1
因为yield支持其返回类型为 的方法IEnumerable<T>并GetFiles()返回Task<IEnumerable<T>>
查看以下内容:
public IEnumerable<StorageFile> GetFiles(StorageFolder folder)
{
// your code here
}
public Task<IEnumerable<StorageFile>> GetFilesAsync(StorageFolder folder)
{
return Task.Run(() => GetFiles(folder));
}
Run Code Online (Sandbox Code Playgroud)
然后你可以做foreach (var file in GetFiles(folder))或foreach (var file in await GetFilesAsync(folder))
编辑:啊,您谈论的 IAsyncEnumerable 在您发布答案的日期中不存在
| 归档时间: |
|
| 查看次数: |
5768 次 |
| 最近记录: |