c# - 为什么等待之前的异常不会在没有等待的情况下抛出?
问题描述
考虑以下代码:
static async Task ThrowException()
{
throw new Exception("exception 1");
Thread.Sleep(1000);
await Task.Delay(1000);
throw new Exception("exception 2");
}
static async Task Sleep()
{
Console.WriteLine("begin sleep");
Thread.Sleep(1000);
Console.WriteLine("end sleep");
Console.WriteLine("begin delay");
await Task.Delay(1000);
Console.WriteLine("end delay");
}
static async Task Main(string[] args)
{
{
Console.WriteLine("begin var task = Sleep();");
var task = Sleep();
Console.WriteLine("end var task = Sleep();");
Console.WriteLine("begin await task;");
await task;
Console.WriteLine("end await task;");
}
{
try
{
Console.WriteLine("begin var task = ThrowException();");
var task = ThrowException();
Console.WriteLine("end var task = ThrowException();");
Console.WriteLine("begin await task;");
await task;
Console.WriteLine("end await task;");
}
catch(Exception e)
{
Console.WriteLine(e.Message);
}
}
}
结果如下:
begin var task = Sleep();
begin sleep
end sleep
begin delay
end var task = Sleep();
begin await task;
end delay
end await task;
begin var task = ThrowException();
end var task = ThrowException();
begin await task;
exception 1
我的问题是为什么exception 1
出现在“开始等待任务”任务之后但“结束睡眠”出现在“开始等待任务”之前?我认为它之前没有启动一个新线程await Task.Delay()
,它应该发生在同一个线程中Thread.Sleep()
,所以我希望在“end var task = ThrowException();”之前立即抛出“异常 1”
解决方案
这段代码是
static async Task ThrowException()
{
throw new Exception("exception 1");
Thread.Sleep(1000);
await Task.Delay(1000);
throw new Exception("exception 2");
}
如同
static Task ThrowException()
{
Task.Run(() =>
{
throw new Exception("exception 1");
Thread.Sleep(1000);
await Task.Delay(1000);
throw new Exception("exception 2");
}
)
}
诀窍是异常被任务吞噬。然后异常存储在任务中,当您询问任务的结果时,抛出异常。并await
返回任务的结果。
在你的情况下:
try
{
Console.WriteLine("begin var task = ThrowException();");
// 1) Display : "begin var task = ThrowException();"
var task = ThrowException();
// 2) Starts a task that immediately ends with an exception
Console.WriteLine("end var task = ThrowException();");
// 3) Display : "end var task = ThrowException();"
Console.WriteLine("begin await task;");
// 4) Display : "begin await task;"
await task;
// 5) await return the task result,
// in this case it's throw the exception stored in the task.
// Go to in catch
Console.WriteLine("end await task;");
var task = ThrowException();
await task;
}
catch(Exception e)
{
Console.WriteLine(e.Message);
//6) Display the exception message
}
推荐阅读
- javascript - 如何在 Angular 8 中使用 Observable.fromPromise?
- python - 如何将少数名称转换为带引号的实际字符串
- javascript - 将随机 ID 作为参数传递
- c - 使用 GCC 正确地将参数传递给主管调用
- javascript - 如何选择元素的第 n 个子元素并分配 click() 函数?
- python - Python ctypes:_ctypes.py 文件应该在哪里?
- docker - 在 Docker 容器中将 Spyder 连接到远程 Jupyter Notebook
- spring - 有没有办法在没有 Stompendpoints 的情况下使用 spring 消息代理?
- java - 在硒脚本中从excel中获取数据时收到警告
- php - Codeigniter/CSS PDF 打印输出对齐 PDF 位置