为什么async void
是C#的一部分的常见描述适用于事件处理程序。例如:
private async void button_Click(object sender, RoutedEventArgs e)
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync("http://example.com");
var content = await response.Content.ReadAsStringAsync();
this.textBox.Text = content;
}
}
我发现这个原因并不令人满意,因为这种事件处理程序可以在没有async void
的情况下编写,如下所示:
private void button_Click(object sender, RoutedEventArgs e)
{
button_ClickAsync().ForgetTask();
}
private async Task button_ClickAsync()
{
using (var httpClient = new HttpClient())
{
var response = await httpClient.GetAsync("http://example.com");
var content = await response.Content.ReadAsStringAsync();
this.textBox.Text = content;
}
}
static class TaskExtensions { public static void ForgetTask(this Task task) { } }
为什么后者不够好?为什么async void
是C#的必要部分?没有async void
会无法解决什么问题?
答案 0 :(得分:2)
当你展示自己时,它不是必要的。您可以在不使用它的情况下将功能相同的程序写入使用它的程序。它是有用的,因为有时你确实想要创建一个async
方法,它不会暴露任何观察结果的方法,例如你提到的情况。他们是否可以用这样的方式设计这个功能,用户可以用另一种方式完成,是的,你展示了一种可能的方式,C#语言设计师选择另一种方式。
答案 1 :(得分:1)
未启动的async Task
方法的异常将被忽略,触发TaskScheduler.UnobservedTaskException
事件。例如:
static void Main()
{
TaskScheduler.UnobservedTaskException += (object sender, UnobservedTaskExceptionEventArgs args) => { Console.WriteLine(args.Exception.InnerException.Message + " unobserved"); };
try
{
ThrowExceptionInAsyncTask();
Console.WriteLine("ThrowExceptionInAsyncTask not caught");
}
catch (Exception)
{
Console.WriteLine("ThrowExceptionInAsyncTask caught");
}
GC.Collect();
try
{
ThrowExceptionInAsyncVoid();
Console.WriteLine("ThrowExceptionInAsyncVoid not caught");
}
catch (Exception)
{
Console.WriteLine("ThrowExceptionInAsyncVoid caught");
}
GC.Collect();
}
static async Task ThrowExceptionInAsyncTask()
{
throw new InvalidOperationException("ThrowExceptionInAsyncTask");
}
static async void ThrowExceptionInAsyncVoid()
{
throw new InvalidOperationException("ThrowExceptionInAsyncVoid");
}
产地:
ThrowExceptionInAsyncTask not caught ThrowExceptionInAsyncVoid not caught ThrowExceptionInAsyncTask unobserved
答案 2 :(得分:0)
根据我自己的知识,它在两种情况下使用:
您在此处所做的是一个很好的解决方法,但将其视为语言的灵活性,以使开发人员的生活更轻松并简化语言语法。与你的相同的例子是:为什么System.Linq存在于C#中?为什么我们可以使用像myIntArray.Max()这样的语法,同时我们可以迭代数组并找到最大值!
这并不意味着没有其他原因,但我在分享我的想法,我希望有所帮助。