如何从异步方法向调用者抛出异常
本文关键字:调用者 抛出异常 异步方法 | 更新日期: 2023-09-27 17:54:05
今天我读了很多关于async/await的文章,它完全让我大吃一惊。我不明白为什么下面的测试通过了。
[Test]
public void Test()
{
var listener = new AsyncHttpListener();
listener.ListeningAsync();
try
{
new WebClient().DownloadString("http://localhost:8080/");
}
catch (Exception)
{
}
listener.Close();
}
public class AsyncHttpListener
{
private readonly HttpListener listener;
public AsyncHttpListener()
{
listener = new HttpListener();
listener.Prefixes.Add("http://localhost:8080/");
listener.Start();
}
public void Close()
{
listener.Close();
}
public async void ListeningAsync()
{
var context = await listener.GetContextAsync();
HandleContext(context);
}
private void HandleContext(HttpListenerContext context)
{
throw new Exception("test excpetion");
}
}
测试通过,但输出包含:
我期望异常将从任务线程(HandleContext()方法)传输到调用者上下文并测试失败。我怎样才能得到这种行为?
将async void
改为async Task
,将void
改为async Task
:
public async Task ListeningAsync()
{
var context = await listener.GetContextAsync();
HandleContext(context);
}
[Test]
public async Task Test()
{
var listener = new AsyncHttpListener();
await listener.ListeningAsync();
try
{
new WebClient().DownloadString("http://localhost:8080/");
}
catch (Exception)
{
}
listener.Close();
}
有几个很好的理由避免async void
。错误处理就是其中之一。async void
方法引发的错误会直接转到方法启动时当前的SynchronizationContext
。
测试通过的原因是async
方法可能在完成之前返回给调用者。测试运行器看到测试方法返回(尚未抛出异常),并将其标记为"通过"。如果您从测试方法返回Task
,那么测试运行器知道在认为测试完成之前要等待Task
完成。