【发布时间】:2012-03-08 03:50:38
【问题描述】:
我有一些代码可以做这样的事情:
abstract class Data
{
Data(string name, bool load) { if (load) { Load().Wait(); }
abstract Task Load();
}
class XmlData : Data
{
XmlData(string name, bool load = true) : base(name, load) {}
override async Task Load()
{
var file = await GetFileAsync(...);
var xmlDoc = await LoadXmlDocAsync(file);
ProcessXml(xmlDoc);
}
void ProcessXml(XmlDocument xmlDoc)
{
foreach (var element in xmlDoc.Nodes)
{
if (element.NodeName == "something")
new XmlData(element.NodeText);
}
}
}
我似乎(有时)遇到了奇怪的时间问题,最终将代码挂在 GetFileAsync(...) 处。这是由调用的递归性质引起的吗?当我将所有 await 调用更改为实际执行 .Wait() 以完成它们并从本质上摆脱调用的所有异步性质时,我的代码执行得很好。
【问题讨论】:
-
当我附加调试器并中断时,它只是坐着,等待 Load.Wait()。我现在没有它。但据我记得,没有其他任何东西在执行。它只是在等待加载,但似乎没有其他任何事情发生。
-
@gamernb 如果是这种情况,这几乎可以保证在捕获的上下文中等待死锁。看我的回答。
-
在构造函数中调用虚方法通常是个坏主意(例如参见stackoverflow.com/a/448272/224370)
-
是“Load.Wait();”实际上编码为“Load().Wait();” ?
标签: c# asynchronous recursion windows-runtime async-await