Ho problemi a risolvere il problema che sto affrontando con async/attendi.Il metodo asincrono atteso non viene restituito prima che sia richiesto il risultato
In poche parole, ho un controller, decorato con un attributo. Questo attributo ottiene il contenuto specificato da un I/O intenso processo (file system/db/api ecc ...)
Si imposta quindi il contenuto restituito come Dictionary<string, string>
sulla ViewBag
Poi, in una vista , posso fare qualcosa di simile, per recuperare il contenuto:
@(ViewBag.SystemContent["Common/Footer"])
il problema che sto avendo, è la prima volta che viene eseguito, il contenuto non ha restituito, e la chiamata per recuperare il valore da stringa indice fallisce, in quanto non esiste.
Premi F5 e va bene.
azione di controllo è piuttosto semplice:
[ProvideContent("Common/Footer")]
public class ContactDetailsController : Controller
{
public async Task<ActionResult> Index()
{
//omitted for brevity - awaits some other async methods
return View();
}
}
L'attributo
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);
}
EDIT
Cambiare la seguente riga nel mio attributo:
var content = await _contentManager.GetContent(localPath);
To
var content = Task.Factory.StartNew(() =>
manager.GetContent(localPath).Result, TaskCreationOptions.LongRunning).Result;
risolve il problema, ma sento che va contro tutto quello che ho letto su Stephen Clearys blog ...
Non sono un esperto asincrona, ma si' ri definire il contenuto e usarlo subito, non puoi semplicemente cambiarlo in una chiamata sincrona? – DLeh
con contenuto, sto * aspettando * _contentmanager.GetContent - che è asincrono ..... anche se blocco con a. Risultato alla fine, è lo stesso risultato finale – Alex
Ho il sospetto che il problema sia che si sta eseguendo l'override di un metodo sincrono con uno asincrono. Se è necessario eseguire il completamento prima dell'esecuzione dell'azione tes, perché l'hai reso asincrono? – Lee