非同期で再帰(UWP)

非同期で再帰(UWP)

自分用:メモ:

非同期で再帰(UWP)の挙動が安定しない…。

この辺か???

devlights.hatenablog.com

stackoverflow.com


自分でも書いてはみたが...

var buf = new BlockingCollection<IStorageItem>();
var copyDirTask = Task.Run<Task>(async () =>
{
    await this.CopyFolderAsync(s, d, buf);
    buf.CompleteAdding();
});

List<AbstractStorage> result1 = new List<AbstractStorage>();
var outputTask = Task.Run(() =>
{
    foreach (var item in buf.GetConsumingEnumerable())
    {
        Debug.WriteLine(item.Path);
        result1.Add(new AbstractStorage() { Path = item.Path, Storage = item });
    }
});

await Task.WhenAll(copyDirTask, outputTask);


// 再帰
private async Task CopyFolderAsync(StorageFolder sourceContainer, StorageFolder destContainer, BlockingCollection<IStorageItem> buf)
{
    var subDirBufs = new List<BlockingCollection<IStorageItem>>();

    StorageFolder destDir = await destContainer.CreateFolderAsync(sourceContainer.Name, CreationCollisionOption.OpenIfExists);

    buf.Add(destDir);

    // ファイル
    var files = await sourceContainer.GetFilesAsync();
    foreach (var file in files)
    {
        var copied = await file.CopyAsync(destDir, file.Name, NameCollisionOption.ReplaceExisting);
        buf.Add(copied);
    }

    // 非同期で再帰
    var tasks = new List<Task>();
    var folders = await sourceContainer.GetFoldersAsync();
    foreach (var folder in folders)
    {
        var bufSubDir = new BlockingCollection<IStorageItem>();

        tasks.Add(Task.Run(async () =>
        {
            Debug.WriteLine(folder.Path);
            await CopyFolderAsync(folder, destDir, bufSubDir);
            bufSubDir.CompleteAdding();
        }));

        subDirBufs.Add(bufSubDir);
    }

    await Task.WhenAll(tasks).ContinueWith(task =>
    {
        foreach (var subDirBuf in subDirBufs)
        {
            foreach (var item in subDirBuf.GetConsumingEnumerable())
            {
                Debug.WriteLine(item.Path);
                buf.Add(item);
            }
        }
    });

    return;
}