当在不同线程上有多个对Windows.Storage.StorageFolder.GetFolderFromPathAsync的调用时,我将获得ArgumentExceptions。下面是一个再现问题的测试:
[TestMethod]
public async Task ConcurrentGetFolderFromPath()
{
List<Task> tasks = new List<Task>();
for (int i = 0; i < 10; i++)
{
var task = Task.Run(async () =>
{
string localFolderPath = Windows.Storage.ApplicationData.Current.LocalFolder.Path;
//await Task.Yield();
var folder = await Windows.Storage.StorageFolder.GetFolderFromPathAsync(localFolderPath);
});
tasks.Add(task);
}
await Task.WhenAll(tasks);
}我得到的例外是:
System.ArgumentException: Value does not fall within the expected range.
Result StackTrace:
at Windows.Storage.StorageFolder.GetFolderFromPathAsync(String path)
at PCLStorage.Test.FolderTests.<<ConcurrentGetFolderFromPath>b__53>d__55.MoveNext() in c:\git\pclstorage\test\PCLStorage.Test\FolderTests.cs:line 205当我单独运行它时,测试会持续失败,但是当我与其他PCL存储测试一起运行它时,通常会通过测试。
我在这里做错什么了吗?GetFolderFromPathAsync或我所使用的任何其他API只应该从UI线程中使用吗?或者这可能是WinRT存储API中的一个bug?
发布于 2013-07-18 22:01:41
好的,这里的问题是Task.Run以及它处理async delegates的方式。基本上,当你说:
Task.Run(async () => ...)它回到你身边的并不是你所期待的朴素的简Task。它返回包装在另一个任务中的任务,即一个任务。因此,为了获得要查找的任务(检索StorageFolder的任务),需要对外部任务进行await。只需在将其添加到tasks列表时进行更改即可:
tasks.Add(await task);现在,还有第二个问题。您正在从同一个文件夹中读取大量数据,可能是同时进行的。这可能会导致一些AccessExceptions。它也可能不会。我在做这件事时会小心的。
我在WinRT的单元测试中做文件读/写时遇到了问题。幸运的是,我正在使用Mvvm (通过Mvvm ),并且已经将本地存储封装在Controller中。这允许我编写一个LocalStorageController,仅仅是为了单元测试,它允许我对内存中的文件系统执行所有的IO操作(基本上是一个简单的Dictionary<string, byte[]>)。这确实使测试复杂的文件树变得更加困难,但您也可以使用不同的数据结构(例如实际的Tree)来建模您的文件系统。
不管怎么说,我希望这能帮上忙。不过,我很抱歉在你问了这么久之后。编码愉快!
https://stackoverflow.com/questions/16889890
复制相似问题