【发布时间】:2014-08-14 19:07:50
【问题描述】:
我仅限于 Microsoft Async NuGet 包,到目前为止我真的很喜欢 async/await 语法。我有很多方法可以顺利地使用这种技术,但是我遇到了一些问题,试图变得更高级。
我需要加载多个数据源、库存、部门等。我希望顶层方法等待所有源加载,然后继续。代码似乎陷入僵局。我已经做了一些研究,但我的理解中缺少一些东西。
这是顶级调用:
await GlobalData.WaitAsync(GlobalData.DataType.Inventory | GlobalData.DataType.Departments).ConfigureAwait(continueOnCapturedContext: false);
WaitAsync..
public static async Task<bool> WaitAsync(DataType flags)
{
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
Task<bool> task = tcs.Task;
ThreadPool.QueueUserWorkItem(_ =>
{
try
{
List<Task> tasks = new List<Task>();
foreach (DataType t in Enum.GetValues(typeof(DataType)))
{
if (t != DataType.None && flags.HasFlag(t))
{
tasks.Add(GetModel(t).GetTask());
}
}
/* Remove any tasks that are null. */
tasks.RemoveAll(t => t == null);
Task.WaitAll(tasks.ToArray());
tcs.SetResult(true);
}
catch (Exception)
{
throw;
}
});
return await task;
最后,在 GetTask(..) 内部
public override Task GetTask()
{
/* If the task is not null, another caller has asked for the data already, hook into the callback. */
if (m_LoadingTask != null)
{
return m_LoadingTask;
}
else
{
/* Only load if the bindingList is null, return the Task. */
if (m_Data == null)
{
return this.LoadAsync();
}
}
return null;
}
我可以看到代码按预期执行。 Task.WaitAll(...) 返回并执行 tcs.SetResult(true),但永远不会回到顶层 await。
我能做些什么来解决这个问题?
提前致谢。
【问题讨论】:
-
为什么你的
WaitAsync方法完全是异步方法?您可以只从同步方法返回tcs.Task...以return await ...结尾并且没有任何其他await表达式的异步方法始终至少是重构的候选。这不是这里的问题,而是需要考虑的问题。 (同样,任何时候你有一个只是throw;的 catch 块,考虑删除它......唯一的好处是能够在它上面放置一个断点。) -
您好 Jon,感谢您的及时回复。您对我使用 async/await 的观察是正确的。看来我错过了重点。我将使用 TAP 模型进行重构,并将 aysnc/await 仅应用于我的顶级方法。我会回复结果。谢谢!
-
明确地说,我不希望它改变行为,只是简化代码。
标签: .net winforms asynchronous .net-4.0 async-await