.Net Task<T>的一种比较神奇的卡死情况(Wait/Result卡死, await能得到结果)
出现的环境.Net4.0 + WebApi1(4.0.30506.0) + Microsoft.Bcl.Async.1.0.168
自己死活看不出原因, 分享出来给大家看看,希望有人能找到问题的关键
出现错误的是下面这两个模块
下面的CorsMessageHandler,抄的http://www.cnblogs.com/artech/p/cors-4-asp-net-web-api-04.html, 做了部分修改
public class CorsMessageHandler : DelegatingHandler
{
private static readonly CorsAttribute DEFAULT_CORS = new CorsAttribute("*");//默认支持所有 protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
try
{
//得到描述目标Action的HttpActionDescriptor
HttpMethod originalMethod = request.Method;
bool isPreflightRequest = request.IsPreflightRequest();
if (isPreflightRequest)
{
string method = request.Headers.GetValues("Access-Control-Request-Method").First();
request.Method = new HttpMethod(method);
}
HttpConfiguration configuration = request.GetConfiguration();
HttpControllerDescriptor controllerDescriptor = configuration.Services.GetHttpControllerSelector().SelectController(request);
HttpControllerContext controllerContext = new HttpControllerContext(request.GetConfiguration(), request.GetRouteData(), request)
{
ControllerDescriptor = controllerDescriptor
};
//避免权限错误
//HttpActionDescriptor actionDescriptor = configuration.Services.GetActionSelector().SelectAction(controllerContext); //根据HttpActionDescriptor得到应用的CorsAttribute特性
CorsAttribute corsAttribute = null;
//corsAttribute = actionDescriptor.GetCustomAttributes<CorsAttribute>().FirstOrDefault();
corsAttribute = corsAttribute?? controllerDescriptor.GetCustomAttributes<CorsAttribute>().FirstOrDefault();
if (null == corsAttribute)
{
corsAttribute = DEFAULT_CORS;
//return base.SendAsync(request, cancellationToken);
} //利用CorsAttribute实施授权并生成响应报头
IDictionary<string, string> headers;
request.Method = originalMethod;
bool authorized = corsAttribute.TryEvaluate(request, out headers);
HttpResponseMessage response;
if (isPreflightRequest)
{
if (authorized)
{
response = new HttpResponseMessage(HttpStatusCode.OK);
}
else
{
response = request.CreateErrorResponse(HttpStatusCode.BadRequest, corsAttribute.ErrorMessage);
}
}
else
{
var tmp = base.SendAsync(request, cancellationToken);
tmp.Wait();
response = tmp.Result;
} if (headers != null)
{
foreach (var item in headers)
{
response.Headers.Add(item.Key, item.Value);
}
}
return response;
}
catch
{
}
//catch -> fallback
return await base.SendAsync(request, cancellationToken);
}
}
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CorsAttribute : Attribute
{
public Uri[] AllowOrigins { get; private set; }
public string ErrorMessage { get; private set; } public CorsAttribute(params string[] allowOrigins)
{
var tmp = (allowOrigins ?? new string[]);
if (tmp.Length == && "*" == tmp[])
{
this.AllowOrigins = null;
}
else
{
this.AllowOrigins = tmp.Select(origin => new Uri(origin)).ToArray();
}
} public bool TryEvaluate(HttpRequestMessage request, out IDictionary<string, string> headers)
{
headers = null; //bugfix: GetValues在找不到时会报错
IEnumerable<string> origins;
if (request.Headers.TryGetValues("Origin", out origins))
{
string origin = origins.FirstOrDefault();
if (!String.IsNullOrEmpty(origin))
{
Uri originUri = new Uri(origin);
if (this.AllowOrigins == null || this.AllowOrigins.Contains(originUri))//支持"*"
{
headers = this.GenerateResponseHeaders(request);
return true;
}
}
}
this.ErrorMessage = "Cross-origin request denied";
return false;
} private IDictionary<string, string> GenerateResponseHeaders(HttpRequestMessage request)
{
//设置响应报头"Access-Control-Allow-Methods"
string origin = request.Headers.GetValues("Origin").First();
Dictionary<string, string> headers = new Dictionary<string, string>();
headers.Add("Access-Control-Allow-Origin", origin);
if (request.IsPreflightRequest())
{
//设置响应报头"Access-Control-Request-Headers"
//和"Access-Control-Allow-Headers"
string requestHeaders = request.Headers.GetValues("Access-Control-Request-Headers").FirstOrDefault();
if (!string.IsNullOrEmpty(requestHeaders))
{
headers.Add("Access-Control-Allow-Headers", requestHeaders);
}
//string requestMethods = request.Headers.GetValues("Access-Control-Request-Method").FirstOrDefault();
//if (!string.IsNullOrEmpty(requestHeaders))
//{
// headers.Add("Access-Control-Allow-Methods", requestMethods + ", OPTIONS");
//}
//else
//{
headers.Add("Access-Control-Allow-Methods", "*");
//}
}
headers.Add("Access-Control-Allow-Credentials", "true");//true, 允许跨域传cookie, 要在POST的返回值中也存在
return headers;
}
}
一个简单的异常过滤器
public class JsonExceptionFilter : FilterAttribute, IExceptionFilter//, IActionFilter
{ public Task ExecuteExceptionFilterAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
{
return Task.Factory.StartNew((obj) =>
{
CancellationToken ct = (CancellationToken)obj;
if (actionExecutedContext.Exception != null)
{
var res = new ResultModel<String>(false, actionExecutedContext.Exception.GetType().ToString());
var resText = JsonConvert.SerializeObject(res);
if (actionExecutedContext.Response == null)
{
actionExecutedContext.Response = new HttpResponseMessage();
}
actionExecutedContext.Response.Content = new StringContent("{\"State\":-255}", Encoding.UTF8, "application/json");
}
}, cancellationToken, cancellationToken);
}
}
现在存在的问题是如果Action内部有异常被过滤器捕获, CorsMessageHandler就卡死在
var tmp = base.SendAsync(request, cancellationToken);
response = tmp.Result;//卡死在这里, 用tmp.Wait();也是一样卡死
调试看task的State是WaitingForActivation, 但是用Wait/Result无限期卡死无法得到结果, 但是用await(Microsoft.Bcl.Async引入)就不存在问题, 能正常执行出结果
.Net Task<T>的一种比较神奇的卡死情况(Wait/Result卡死, await能得到结果)的更多相关文章
- java Quartz定时器任务与Spring task定时的几种实现,
java Quartz定时器任务与Spring task定时的几种实现 基于java 的定时任务实现, Quartz 时间详细配置 请查阅 http://www.cnblogs.com/si ...
- 四大组件之Activity Task任务栈4种启动模式
1.启动模式 standard,创建一个新的Activity. singleTop,栈顶不是该类型的Activity,创建一个新的Activity.否则,onNewIntent. singleTask ...
- Delegate、Thread、Task、ThreadPool几种方式创建异步任务性能对比
开始预测的结果是 Task>Delegate>ThreadPool>>Thread. (一)测试代码 static async Task<int> AsyncTas ...
- async await task.Result 卡死
在如下代码中: public async Task<string> GetData() { return await DoWork(); } 在UI线程中调用 var data = Get ...
- C++:四种必须使用初始化列表情况
[c++]必须在类初始化列表中初始化的几种情况 1. 类成员为const类型 2. 类成员为引用类型 复制代码 #include <iostream> using namesp ...
- vue-router两种模式,到底什么情况下用hash,什么情况下用history模式呢?
转:https://segmentfault.com/q/1010000010340823/a-1020000010598395 为什么要有 hash 和 history 对于 Vue 这类渐进式前端 ...
- JAVA中空指针异常报错的几种可能坑你的情况
一.局部变量覆盖掉其他变量导致无法使用. 在做Java客户管理的项目的时候,eclipse报出了个空指针异常的错误,但反复检查也并没感觉出错误,调用的数组给它初始化而且赋值了,但是编译器很顽强的报了一 ...
- 在web项目中获取ApplicationContext上下文的3种主要方式及适用情况
最近在做web项目,需要写一些工具方法,涉及到通过Java代码来获取spring中配置的bean,并对该bean进行操作的情形.而最关键的一步就是获取ApplicationContext,过程中纠结和 ...
- 数据库SQL调优的几种方式 EFcore读的情况下使用 AsNoTracking非跟踪查询
不要用GUID 当主键 没有规律 可以用雪花ID DBA 优化法则 硬件资源是根本,DBA是为了充分利用硬件资源 一般清空下可以不使用外键 可以提高性能 合理使用临时表 临时表分页; 一些查询语句加w ...
随机推荐
- asp.net identity 2.2.0 中角色启用和基本使用(三)
创建控制器 第一步:在controllers文件夹上点右键>添加>控制器, 我这里选的是“MVC5 控制器-空”,名称设置为:RolesAdminController.cs 第二步:添加命 ...
- 【腾讯bugly干货分享】Android自绘动画实现与优化实战——以Tencent OS录音机波形动
前言 本文为腾讯bugly的原创内容,非经过本文作者同意禁止转载,原文地址为:http://bugly.qq.com/bbs/forum.php?mod=viewthread&tid=1180 ...
- node(websocket)
websocket原本是html5下实现长链接的一个特性,当前已被众多浏览器支持. 在websocket协议中,首先通过http交换一次握手,明确将协议升级至websocket.同时建立一个TCP通道 ...
- AMD加载器实现笔记(三)
上一篇文章中我们为config添加了baseUrl和packages的支持,那么这篇文章中将会看到对shim与paths的支持. 要添加shim与paths,第一要务当然是了解他们的语义与用法.先来看 ...
- 基础调试命令 - wt (watch and trace)
本文介绍windbg动态调试过程中一个非常有用的命令,wt的用法. wt命令 wt命令之所以称为wt是因为它是watch and trace的简称,即用来观察和跟踪的命令.这个命令一般用在动态调试而不 ...
- 假如现在有一堆长度大于3小于9的电话号码,用座机呼叫,如果出现这样的号码【123和12345】那么12345将永远不会被拨出,因为拨到123的时候电话已经呼出了,试写一个函数输出所有不能被呼出的电话号码(java实现)
解题: 假如现在有一堆长度大于3小于9的电话号码,用座机呼叫,如果出现这样的号码[123和12345]那么12345将永远不会被拨出,因为拨到123的时候电话已经呼出了,试写一个函数输出所有不能被呼出 ...
- 使用抓包工具SpyNet对你的网络进行监控
步骤1:下载并安装SpyNet Sniffer嗅探器之后,第一次运行SpyNet Sniffer后,将会弹出[Settings(设置)]对话框,在其中选择需要监听对象,如图所示. 步骤2:单击[Act ...
- js模版引擎handlebars.js实用教程——each嵌套
<!DOCTYPE html> <html> <head> <META http-equiv=Content-Type content="text/ ...
- Android获取View对应的Bitmap
我的应用里面有一个需求,将一个画面分享出去,这个画面底层是一个View,所以首先要把这个View转换成Bitmap,然后在分享这个bitmap即可.话不多说,直接上代码. 有个地方需要注意一下:就是/ ...
- IOS Animation-贝塞尔曲线与Layer简单篇(一)
IOS Animation-贝塞尔曲线与Layer简单篇 swift篇 1.介绍 贝塞尔曲线: 贝塞尔曲线是计算机图形图像造型的基本工具,是图形造型运用得最多的基本线条之一.它通过控制曲线上的四个点( ...