Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# StorageFolder.CreateFolderAsync中的奇怪行为_C#_.net_Windows_Async Await - Fatal编程技术网

C# StorageFolder.CreateFolderAsync中的奇怪行为

C# StorageFolder.CreateFolderAsync中的奇怪行为,c#,.net,windows,async-await,C#,.net,Windows,Async Await,我正在为windows应用商店应用程序做一些事情,这是一个通用应用程序项目,我正在windows 8.1笔记本和windows 8.1 Surface Pro 3上调试 我正在尝试在ApplicationData.Current.LocalFolder中创建一些嵌套文件夹。 从主屏幕的构造函数中,我调用 CacheManager.InitializeOfflineFiles().Wait(); CacheManager.InitializeOfflineFiles()的代码是 当我调试它时,它

我正在为windows应用商店应用程序做一些事情,这是一个通用应用程序项目,我正在windows 8.1笔记本和windows 8.1 Surface Pro 3上调试

我正在尝试在ApplicationData.Current.LocalFolder中创建一些嵌套文件夹。 从主屏幕的构造函数中,我调用

CacheManager.InitializeOfflineFiles().Wait();
CacheManager.InitializeOfflineFiles()的代码是

当我调试它时,它并没有通过创建文件夹“2”。没有异常记录,什么也没有。另外,当我在没有调试的情况下运行此命令时(Ctrl+F5),同样的结果是,在本地存储中只创建dir“one/two”

这是一种误解异步编程的情况吗

这是:

CacheManager.InitializeOfflineFiles().Wait();
正在导致应用程序死锁。这就是为什么你会看到“绞刑”行为。奇怪的是,您似乎看到正在创建文件夹1和文件夹2,因为我假设在执行第一个
wait
时会死锁

这就是你的原因

由于构造函数不能是异步的,因此请使用“Initialize Pattern”()来执行异步代码:

public Task InitializeAsync()
{
    return InitializeOfflineFilesAsync()
}
从您的代码中,从
async
上下文方法调用它,可能是一个事件处理程序:


这个故事的寓意是,不要通过构造函数调用异步方法

事实证明,我可以从构造函数调用异步方法。 在构造函数中:

 var task = Task.Run(async () =>
   {
       return await CacheManagerInitializeOfflineFiles();
   });
   string dummy = task.Result;
同一类中调用创建存储目录的异步方法的方法:

private async Task<string> CacheManagerInitializeOfflineFiles()
{
    await CacheManager.InitializeOfflineFiles();
    return "done";
}
专用异步任务CacheManagerInitializeOfflineFiles()
{
等待CacheManager.InitializeOfflineFiles();
返回“完成”;
}

我真的不想设置“初始化应用程序”按钮,这将是一个糟糕的设计:)

要避免死锁,请尝试以下方法:

StorageFolder s1 = await ApplicationData.Current.LocalFolder.CreateFolderAsync("one", CreationCollisionOption.OpenIfExists).AsTask().ConfigureAwait(false);

我想过这个,但是,为什么它在第一次
CreateFolderAsync
调用时没有死锁,但只在第三次调用时死锁?@thomasleveque我知道,这很奇怪。我们肯定丢失了一些数据。我看不出有任何其他原因导致此挂起,但我无法解释仅在第二次
等待后挂起的原因。谢谢您的回答。我承认我对这个WindowsAPI一无所知,从我的noob问题中可以明显看出这一点,但以这种方式出现死锁确实令人沮丧。在Java中,您必须努力工作以避免死锁,这里操作系统会为您做到这一点。我真的很想有一个同步初始化块,但它们没有为存储提供任何同步方法。“这真是太愚蠢了!”维多利亚·奥涅斯库我理解你的沮丧。这种情况经常发生。我每周回答两次这样的问题。之所以会发生这种情况,是因为
asyncwait
和异步API比人们想象的要复杂。
private async Task<string> CacheManagerInitializeOfflineFiles()
{
    await CacheManager.InitializeOfflineFiles();
    return "done";
}
StorageFolder s1 = await ApplicationData.Current.LocalFolder.CreateFolderAsync("one", CreationCollisionOption.OpenIfExists).AsTask().ConfigureAwait(false);