异步任务阻止Web请求

时间:2017-04-09 09:04:31

标签: c# asynchronous asp.net-web-api2

我有一个Mvc Web Api,我正在使用异步jquery调用一个长时间运行的动作(1分钟)但是每个东西都会被阻塞,直到结果返回。

这是我的行动

 [System.Web.Http.HttpGet]
    public async Task<JsonResult> GetParsedApplicationsAsync(string className, string actionName)
    {
        var userRoles = Users.Profile.GetCurrentOrNew().Roles.Select(x => x.Id);
        var sss = AppDomain.CurrentDomain.GetAssemblies();
        var assemblies = sss
            .SelectMany(x => x.GetTypes())
            .Where(x => typeof(IAppSearch).IsAssignableFrom(x));


        var l = new List<decimal?>();
        foreach (var userRole in userRoles)
        {
            l.Add(userRole);
        }
        var apps =
            new VwApplicationsDetailsDap().GetByRoleIds(l.ToArray(), Request.QueryString, "", pagenation: false);


        // Long Running method
        var action = await Task.Factory.StartNew(() =>
        {
            // create instance of class 
            var type = assemblies.FirstOrDefault(x => x.Name == className);
            var instance = Activator.CreateInstance(type, apps);
            return type.GetMethod(actionName).Invoke(instance, BindingFlags.IgnoreCase, null, null, null);

        });
        return await Task.FromResult(Json(action, JsonRequestBehavior.AllowGet));

    }

我也试过var action = await Task.Run(() => 而不是await Task.Factory.StartNew

我该怎么办?

1 个答案:

答案 0 :(得分:0)

看起来您的长时间运行方法正在被动态调用,并且您正在等待异步方法中的结果,这将使线程返回到线程池。

但是因为您正在使用Task.Factory.StartNew,所以您开始处理新线程,并在那里同步运行阻塞线程的工作(这比直接从{{调用阻塞代码更糟糕一点) 1}})。

底线是,如果您的响应需要此长时间运行方法的结果,则应该使用此方法GetParsedApplicationsAsync,然后在动态调用它时,将结果转换为async和{{1结果。

最后提示,您只需返回结果而不是Task<T>,因此您的最后一行应为:

await