在我的应用程序(Windows 8 Metro)中,我以序列化格式将一些对象存储在本地文件夹中。这是阅读的方法(见下文)。
如果我用Task.Run调用此方法,我可以得到对象:
var entity= Task.Run<Entity>(() => GetASync<Entity>(file)).Result;
但如果我使用await关键字,它不起作用 - 在线程停止的方法中的A行(ReadObject)上退出,没有错误或异常:
var entity= await GetASync<Entity>(file);
也许我不建议使用await / async吗?
方法
private async Task<T> GetASync<T>(IStorageFile file) where T : class
{
try
{
if (file != null)
{
IRandomAccessStream readStream = await file.OpenAsync(FileAccessMode.Read);
IInputStream inputStream = readStream.GetInputStreamAt(0);
using (XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(inputStream.AsStream(), XmlDictionaryReaderQuotas.Max))
{
DataContractSerializer serializer = new DataContractSerializer(typeof(T));
var entity = serializer.ReadObject(reader); //line A - here the problem
return entity as T;
}
}
else
{
return null;
}
}
catch (FileNotFoundException)
{
return null;
}
catch (Exception)
{
throw;
}
}
答案 0 :(得分:3)
好吧,我不知道为什么你的代码不起作用。我怀疑是一个死锁,但不应该是一个。 :)
但是,我确实有一些性能建议可能会避免这个副作用。第一种是使用ConfigureAwait(false)
:
IRandomAccessStream readStream = await file.OpenAsync(FileAccessMode.Read)
.StartAsTask()
.ConfigureAwait(false);
另一种是将文件读入内存(异步),然后解析它。 (我假设您的代码中每个文件存储一个对象)。
答案 1 :(得分:1)
从http://social.msdn.microsoft.com/Forums/en-US/async/thread/3f192a81-073a-47ea-92e2-5ce02bf5ad33进行反击:
您遇到了Microsoft在BUILD会议上分发的.NET开发人员预览版中的已知问题。
问题是由WinRT UI线程的一些细微特性引起的。因此,如果从UI线程执行,任何阻止来自托管代码的WinRT流-IO都将导致死锁。异步IO(例如ReadAsync
)可以正常工作。开发团队意识到了这个问题,并正在努力解决它。
但请注意,即使问题得到解决,在UI线程上执行阻止IO也不是一个好主意。您的应用程序将在操作期间阻止并无响应。有些.NET API没有异步等效(甚至),甚至一旦他们这样做,转换代码可能需要工作。如果必须执行阻塞IO操作,请确保将其卸载到线程池:
DoUIStuff();
Int32 x = await Task.Run(() => {
OpenStream();
PerformBlockingIO();
ProcessResults();
return ComputeIOResults();
});
UseIOResults(x);
这样可以始终保持应用程序的响应速度。作为副作用,您还将解决上述错误并避免死锁。