我需要在Global.asax中调用我的数据库上的一些异步操作.例如在Application_AuthenticateRequest中我需要针对数据库验证用户是否可以使用异步任务?
问题
我有一个api GET方法来检索站点配置.我正在使用httpClient和GetAsync()方法来做到这一点.
HttpResponseMessage response = await client.GetAsync("api/{0}/config", id);
Run Code Online (Sandbox Code Playgroud)
由于我需要跨站点进行此配置,因此我计划使用全局操作过滤器.
题
如何在MVC动作过滤器中调用异步方法?或者这个问题有更好的解决方案吗?
我已经看过多个SO问题(MVC 4中的异步动作过滤器),但我没有找到满意的解决方案.
我正在编写一个Action Filter(继承自ActionFilterAttribute),它用于HttpClient将数据POST到方法中的外部服务器OnResultExecuted.HttpClient有一个PostAsync返回等待的方法Task<HttpResponseMessage>.
public override void OnResultExecuted(ResultExecutedContext filterContext)
{
using (var client = new HttpClient())
{
var task = client.PostAsync(GetUri(), GetContent());
var result = task.Result; // blocking
}
}
Run Code Online (Sandbox Code Playgroud)
MVC 4中对Async动作过滤器的接受答案表明它在MVC 4中是不可能的.
这在MVC 5中是否仍然如此,如果是这样,在不阻塞线程的情况下调用此异步方法的最佳方法是什么?
当我在HttpClient调用中使用async-await方法(如下例所示)时,此代码会导致死锁.用a替换async-await方法t.ContinueWith,它可以正常工作.为什么?
public class MyFilter: ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext filterContext) {
var user = _authService.GetUserAsync(username).Result;
}
}
public class AuthService: IAuthService {
public async Task<User> GetUserAsync (string username) {
var jsonUsr = await _httpClientWrp.GetStringAsync(url).ConfigureAwait(false);
return await JsonConvert.DeserializeObjectAsync<User>(jsonUsr);
}
}
Run Code Online (Sandbox Code Playgroud)
这有效:
public class HttpClientWrapper : IHttpClient {
public Task<string> GetStringAsync(string url) {
return _client.GetStringAsync(url).ContinueWith(t => {
_log.InfoFormat("Response: {0}", url);
return t.Result;
});
}
Run Code Online (Sandbox Code Playgroud)
这段代码会死锁:
public class HttpClientWrapper : IHttpClient {
public async Task<string> GetStringAsync(string url) { …Run Code Online (Sandbox Code Playgroud) 我无法解决我遇到异步/等待的问题.
简而言之,我有一个控制器,用属性装饰.此属性从i/o密集型进程(filesystem/db/api等...)获取指定的内容
然后,它将返回的内容设置为Dictionary<string, string>ViewBag上的内容
然后,在视图中,我可以做这样的事情,以检索内容:
@(ViewBag.SystemContent["Common/Footer"])
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是,它第一次运行,内容没有返回,并且通过字符串索引检索值的调用失败,因为它不存在.
点击F5,没关系.
控制器动作非常简单:
[ProvideContent("Common/Footer")]
public class ContactDetailsController : Controller
{
public async Task<ActionResult> Index()
{
//omitted for brevity - awaits some other async methods
return View();
}
}
Run Code Online (Sandbox Code Playgroud)
属性
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 …Run Code Online (Sandbox Code Playgroud)