一、问题简述:
跟主线程并列的异步线程(非阻塞线程)上。
通过
await TaskRun(()=>{}};
开启新的线程并且阻塞等待的话,线程就会丢失或者崩溃。这时候用try{}catch(){}的方式也捕获不到异常。
只有一个出现在System.Web.dll内部的异常。我尝试在Vs 2015上面加载一些System.Web.pdb文件,但是没有找到合适的。
二、伪代码重新描述:
假设有同步Action和异步两个Action
public ActionResult Index()
{
DoworkAsync();
return SendHtml("ok");
}
public async Task<string> Get()
{
DoworkAsync();
return "OK";
}
然后还有两个具体工作的方法,要求按照顺序执行里面,DoworkAsync是一个同步改成异步的await Task.Run
protected async Task DoworkAsync()
{
int UserId
//封装到另一方法里面也没用
//await DoworkAsync2();
await Task.Run(() =>
{
//★重点在此处
System.Threading.Thread.Sleep(6100);
//真正代码
UserId=55;
});
//阻塞之后继续执行的代码
var user = await GetUserAsync(UserId);
}
public async Task<UserInfo> GetUserAsync(int id)
{
var Reuslt = await Db.GetUserAsync(id);
}
protected async Task DoworkAsync2()
{
await Task.Run(() =>
{
System.Threading.Thread.Sleep(6100);
//真正代码
});
}
三、调试结果
1、线程睡眠模拟
在【★重点】那里,不管是Thread.Sleep()还Task.Delay()
都会线程崩溃。
2、实际WebRequest测试
在【★重点】那里,不管是同的方法WebRequest还是await 异步的方法GetResponseAsync
都会线程崩溃。
3、在【★重点】那里,Thread.Sleep()休眠时间为70的时候,第一次可以走到
//阻塞之后继续执行的代码
但是第二次就不行。
因为第一次是时间快,其实是已经崩溃了,【输出】窗口有:
引发的异常:“System.NullReferenceException”(位于 System.Web.dll 中)
四、结论
请问为什么会崩溃,或者求一个替换 await TaskRun(()=>{}};的方案。
因为在VS里面,假如方法名的衣面标识了async,就会提示方法体里面要有await。
看描述 像 async await 死锁问题。
如果action上 async 不准备加的话,底层的 async await 方法 还是把ConfigureAwait(false)加上。
Task.Run 里面的方法里面不要使用任何从DI获取的scope作用域的对象。 请求结束后这些对象就被释放了。
你上面这两段代码,活还没干完,就直接return了。也就意味着DoworkAsync返回的Task你不管了,如果Task有错误,垃圾回收的时候自然在后台报错了。
问题描述感觉有点混乱,改了一下你的代码,供参考