FileIO.ReadTextAsync偶尔挂起 [英] FileIO.ReadTextAsync occasionally hangs
问题描述
我只是尝试的WinRT和一个演示程序我创建是一个基本的记事本风格的应用程序加载哪些/保存到本地存储。虽然我熟悉正确的异步
办法构建WinRT的应用程序,我的演示应用程序是使用同步加载
来让事情变得简单。
现在的问题是,当一个呼叫到加载
做,它的作品了3 2次的应用程序在调用 VAR结果挂起其余时间=等待FileIO.ReadTextAsync(storageFile);
公共类ContentStorage:IContentStorage
{
私人常量字符串文件名=contents.txt;
公共字符串的load()
{
返回LoadAsync()结果。
}
公共无效保存(字符串内容)
{
SaveAsync(内容);
}
私有静态异步任务<串GT; LoadAsync()
{
VAR storageFile =等待LocalFolder.GetFileAsync(文件名);
VAR的结果=等待FileIO.ReadTextAsync(storageFile);
返回结果;
}
私有静态异步无效SaveAsync(字符串内容)
{
VAR storageFile =等待LocalFolder.CreateFileAsync(文件名,CreationCollisionOption.ReplaceExisting);
FileIO.WriteTextAsync(storageFile,内容);
}
私有静态StorageFolder LocalFolder
{
{返回ApplicationData.Current.LocalFolder; }
}
}
我做得非常愚蠢的吗?
FWIW,我尝试改变加载
来只是每一步明确禁止,这提高了吊至1比20,但我还是不明白为什么它挂在所有...
公共字符串的load()
$ { b $ b VAR storageFile = LocalFolder.GetFileAsync(文件名).AsTask()结果。
VAR的结果= FileIO.ReadTextAsync(storageFile).AsTask()结果。
返回结果;
}
虽然我熟悉正确的
异步
办法构建WinRT的应用程序,我的演示应用程序是使用同步加载
让事情变得简单。
块引用>
真的不。混合同步异步代码是非常复杂的。这是简单得多只使用
异步
无处不在。
当一个
异步
法任务的等待后继续执行,将默认恢复到原来的环境。 (我更详细的我异步<支付本/ code> /
)。某些情况下(如UI上下文)只允许一个线程;如果线程被阻塞(例如,在的await
博客文章Task.Result
),那么异步
方法不能进入这一背景下完成它的执行。这导致死锁
有关详细信息:
- 的的
异步
/的await
FAQ 对环境捕获了很多细节和简历。
- 斯蒂芬Toub关于并行团队博客还有另一个博客文章等待和UI,和死锁!哦,我的,其中详细解释了这个特殊的死锁情况
- 我的一个MSDN论坛帖子
这僵局足够有名,它实际上是被微软demo'd:
I'm just experimenting with WinRT and one demo app i'm creating is a basic "notepad" style app which loads/saves to local storage. Whilst I'm familiar with the proper
async
approach for building WinRT apps, my demo app is using a synchronousLoad
to keep things simple.The problem is that when a call is made to
Load
, it works 2 out of 3 times and the rest of the time the app hangs on the callvar result = await FileIO.ReadTextAsync(storageFile);
public class ContentStorage : IContentStorage { private const string FileName = "contents.txt"; public string Load() { return LoadAsync().Result; } public void Save(string content) { SaveAsync(content); } private static async Task<string> LoadAsync() { var storageFile = await LocalFolder.GetFileAsync(FileName); var result = await FileIO.ReadTextAsync(storageFile); return result; } private static async void SaveAsync(string content) { var storageFile = await LocalFolder.CreateFileAsync(FileName, CreationCollisionOption.ReplaceExisting); FileIO.WriteTextAsync(storageFile, content); } private static StorageFolder LocalFolder { get { return ApplicationData.Current.LocalFolder; } } }
Am I doing something extraordinarily stupid here?
FWIW, I experimented with changing
Load
to just explicitly block on each step and this improves the hanging to 1 in 20, but I still don't understand why it's hanging at all...public string Load() { var storageFile = LocalFolder.GetFileAsync(FileName).AsTask().Result; var result = FileIO.ReadTextAsync(storageFile).AsTask().Result; return result; }
解决方案Whilst I'm familiar with the proper
async
approach for building WinRT apps, my demo app is using a synchronousLoad
to keep things simple.Not really. Mixing synchronous with asynchronous code is extremely complex. It's far simpler to just use
async
everywhere.When an
async
method continues execution after waiting for a task, it will return to its original context by default. (I cover this in more detail in myasync
/await
blog post). Some contexts (such as UI contexts) only permit a single thread; if that thread is blocked (e.g., onTask.Result
), then theasync
method cannot enter that context to complete its execution. This causes a deadlock.For more information:
- The
async
/await
FAQ has a lot of detail on the context capture and resume.- Stephen Toub on the Parallel Team Blog has another blog post Await, and UI, and deadlocks! Oh, my!, which explains this particular deadlock situation in detail.
- I wrote an exhaustive answer for this kind of deadlock in an MSDN forum post.
This deadlock is famous enough that it's actually been demo'd by Microsoft:
- By Stephen Toub at the BUILD conference (Sept 16, 2011).
- By Lucian Wischik at DevConnections (Mar 26, 2012).
这篇关于FileIO.ReadTextAsync偶尔挂起的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!