面试题答案
一键面试- 异常处理与同步编程的不同:
- 在同步编程中,异常会立即中断当前代码的执行,并沿着调用栈向上抛出,直到被捕获。捕获异常使用
try - catch
块,在同步代码块内直接捕获异常。 - 在使用
Async
和Await
的异步编程中,异步方法返回Task
或Task<T>
,异常不会立即中断执行流。Await
表达式会暂停当前异步方法的执行,直到所等待的Task
完成。如果Task
以故障状态完成(即抛出异常),Await
会将该异常重新抛出,以便在当前异步方法中捕获处理。异常处理同样使用try - catch
块,但要放在包含Await
的异步方法内。
- 在同步编程中,异常会立即中断当前代码的执行,并沿着调用栈向上抛出,直到被捕获。捕获异常使用
- 代码示例:
using System;
using System.Threading.Tasks;
class Program
{
static async Task Main()
{
try
{
await OuterAsync();
}
catch (Exception ex)
{
Console.WriteLine($"全局捕获到异常: {ex.Message}");
}
}
static async Task OuterAsync()
{
try
{
await InnerAsync();
}
catch (InvalidOperationException ex)
{
Console.WriteLine($"OuterAsync捕获到InvalidOperationException异常: {ex.Message}");
}
}
static async Task InnerAsync()
{
await Task.Delay(1000);
throw new InvalidOperationException("模拟InnerAsync抛出的InvalidOperationException异常");
}
}
上述C#代码演示了在异步方法链中如何捕获和处理异常。InnerAsync
方法模拟抛出一个InvalidOperationException
异常,OuterAsync
方法捕获该特定类型的异常进行处理,如果未被OuterAsync
捕获,异常会继续向上抛出,在Main
方法中被全局捕获。不同编程语言的Async
和Await
实现细节可能略有不同,但异常处理的核心思路一致。例如在Python中:
import asyncio
async def inner_async():
await asyncio.sleep(1)
raise ValueError("模拟inner_async抛出的ValueError异常")
async def outer_async():
try:
await inner_async()
except ValueError as ex:
print(f"outer_async捕获到ValueError异常: {ex}")
async def main():
try:
await outer_async()
except Exception as ex:
print(f"全局捕获到异常: {ex}")
if __name__ == "__main__":
asyncio.run(main())
Python代码中同样展示了在异步方法链中捕获异常的过程,inner_async
抛出ValueError
,outer_async
捕获该异常,若未捕获则在main
函数中全局捕获。