我建议您在 中启动异步加载Application_Start
,然后await
在您的 MVC 操作中完成它。
您可以通过将 保存Task<Dictionary<..>>
到静态变量然后对其进行每个异步操作来轻松完成此操作await
。
// Or in a repository or whatever...
public static class SharedData
{
public static Task<Dictionary<int, string>> MyDictionary;
}
...
Application_Start(..)
{
// Start the dictionary filling, but don't wait for it to complete.
// Note that we're saving the Task, not await'ing it.
MyDictionary = MyLibrary.GetDictionary();
}
然后在每个需要它的异步操作中:
public async Task<ActionResult> Get()
{
// Asynchronously wait for the dictionary to load if it hasn't already.
var dict = await SharedData.MyDictionary;
...
return View();
}
或者,您可以为此使用异步延迟初始化。异步延迟初始化由 Stephen Toub首次公开;我在我的博客上记录了代码并将其升级到 .NET 4.5 ,并且最近将它添加到了我的AsyncEx 库中。
使用AsyncLazy<T>
,您的代码将如下所示:
// Or in a repository or whatever...
public static class SharedData
{
public static AsyncLazy<Dictionary<int, string>> MyDictionary =
new AsyncLazy<Dictionary<int, string>>(async () =>
{
var ret = new Dictionary<int, string>();
await MyLibrary.FillDictionary(ret);
return ret;
});
}
然后在每个需要它的异步操作中:
public async Task<ActionResult> Get()
{
// Asynchronously wait for the dictionary to load if it hasn't already.
var dict = await SharedData.MyDictionary;
...
return View();
}
异步延迟初始化具有延迟的能力,因此需要特定字典的第一个操作将await
它。如果有未使用的字典,则永远不会加载它们。