递归的异步会破坏我的大脑

时间:2015-05-15 15:16:50

标签: c# recursion async-await win-universal-app iot

我正在尝试编写一个简单的通用应用程序,它可以显示来自网络/ SAN的媒体文件。 我设法让这个东西端到端地工作,我很难以可靠的方式从网络中获取文件。

我感觉这是由于我对C#中的异步和/或XAML应用程序中的数据绑定的不了解,但我无法找到解决方法。

using Windows.Storage;

// Private field to keep files
private BlockingCollection<StorageFile> fileList = new BlockingCollection<StorageFile>();

// Called after page initialization
private async Task InitFilesAsync()
{
    var deviceRoot = KnownFolders.MediaServerDevices;
    await WalkFolderAsync(deviceRoot);
    foreach (var f in fileList)
    {
        this.lbxFiles.Items.Add(f);
    }
}

WalkFolder方法如下所示:

private async Task WalkFolderAsync(StorageFolder parent)
{   
    var items = await parent.GetItemsAsync();
    foreach(var item in items)
    {
        if (item.IsOfType(StorageItemTypes.Folder))
        {
            await WalkFolderAsync((StorageFolder)item);
        }
        else if (item.IsOfType(StorageItemTypes.File))
        {
            fileList.Add((StorageFile)item);
        }
    }
}

在某种程度上工作正常;但有时会有0个文件通过,有时是5个或6个文件,偶尔会有15个文件通过。

更新 我根据评论中的建议略微重构了我的代码,但这没有改进。

更新#2 真的没有运气。看起来像递归异步的东西(或者确实是绑定)可能不是问题;但可能是设备本身?我已经尝试过处理任何等待呼叫异常。我偶尔会拒绝访问,但这又不可重现。

1 个答案:

答案 0 :(得分:3)

根本问题是您使用async void。您应使用async void作为事件处理程序。由于他们不会返回任务,您可以await直到完成,他们会强制您List不支持的不需要的多线程。

在迭代之前你也不要等待列表填满,这样你就有了竞争条件。

你应该让你的async方法返回Taskawait这些方法,这些方法可以让你的#34;行走&#34;异步但顺序。

private async Task InitFilesAsync()
{
    await WalkFolderAsync(KnownFolders.MediaServerDevices);
    foreach (var f in fileList)
    {
        this.lbxFiles.Items.Add(f);
    }
}

private async Task WalkFolderAsync(StorageFolder parent)
{   
    var items = await parent.GetItemsAsync();
    foreach(var item in items)
    {
        if (item.IsOfType(StorageItemTypes.Folder))
        {
            await WalkFolderAsync((StorageFolder)item);
        }
        else if (item.IsOfType(StorageItemTypes.File))
        {
            fileList.Add((StorageFile)item);
        }
    }
}