【发布时间】:2015-06-13 16:23:18
【问题描述】:
我无法解决我遇到的异步/等待问题。
简而言之,我有一个控制器,装饰有一个属性。 该属性从一个 i/o 密集型进程(filesystem / db / api etc...)中获取指定的内容
然后它将返回的内容设置为 ViewBag 上的 Dictionary<string, string>
然后,在一个视图中,我可以做这样的事情来检索内容:
@(ViewBag.SystemContent["Common/Footer"])
我遇到的问题是,它第一次运行时,内容没有返回,并且通过字符串索引检索值的调用失败,因为它不存在。
按F5,没问题。
控制器动作非常简单:
[ProvideContent("Common/Footer")]
public class ContactDetailsController : Controller
{
public async Task<ActionResult> Index()
{
//omitted for brevity - awaits some other async methods
return View();
}
}
属性
public override async void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.Result is ViewResult)
{
var localPath = filterContext.RouteData.Values["controller"] + "/" + filterContext.RouteData.Values["action"];
if (!_useControllerActionAsPath)
localPath = _path;
var viewResult = filterContext.Result as ViewResult;
//this seems to go off and come back AFTER the view requests it from the dictionary
var content = await _contentManager.GetContent(localPath);
if (viewResult.ViewBag.SystemContent == null)
viewResult.ViewBag.SystemContent = new Dictionary<string, MvcHtmlString>();
viewResult.ViewBag.SystemContent[localPath] = new DisplayContentItem(content, localPath);
}
编辑
在我的属性中更改以下行:
var content = await _contentManager.GetContent(localPath);
到
var content = Task.Factory.StartNew(() =>
manager.GetContent(localPath).Result, TaskCreationOptions.LongRunning).Result;
解决了这个问题,但我觉得这与我在 Stephen Clearys 博客上读到的所有内容都背道而驰......
【问题讨论】:
-
我不是异步专家,但是您正在定义内容并立即使用它,您不能将其更改为同步调用吗?
-
有内容,我在 awaiting _contentmanager.GetContent - 这是异步的.....即使我最后用 .Result 阻塞,也是一样的结果结果
-
我怀疑问题在于您正在用异步方法覆盖同步方法。如果您需要它在操作执行之前运行完成,为什么要让它异步?
-
为什么我做了哪个异步?被覆盖的方法?
-
是的,
Controller.OnActionExecuting看起来像一个同步方法。如果你让你的异步,那么当Index操作完成时它仍然可以运行。
标签: c# async-await