Async partial void MyPartialMethod()危险吗?

Mic*_*ick 4 c# asynchronous async-await

我已经看到很多关于编写代码的警告,例如...

public async void MyDangerousMethodWhichCouldCrashMyApp...
Run Code Online (Sandbox Code Playgroud)

我已经读过它与Eventhandlers的确定,因为它们必须返回void.但是,部分方法也必须返回void.您可以拥有以下代码......

static void Main(string[] args)
{
    MainAsync().Wait();
    Console.ReadLine();
}

async static Task MainAsync()
{
    MyCodeGeneratedClass c = new MyCodeGeneratedClass();
    try
    {
        await c.MyCodeGeneratedMethod();
    }
    catch(Exception ex)
    {
        Console.WriteLine(ex.Message);
    }
}

public partial class MyCodeGeneratedClass
{
    public async Task MyCodeGeneratedMethod()
    {
        HttpClient client = new HttpClient();
        Console.WriteLine(await client.GetStringAsync("http://msdn.microsoft.com"));
        MyCustomCode();
    }

    partial void MyCustomCode();
}
Run Code Online (Sandbox Code Playgroud)

然后实现为......

partial class MyCodeGeneratedClass
{
    async partial void MyCustomCode()
    {
        HttpClient client = new HttpClient();
        Console.WriteLine(await client.GetStringAsync("http://msdn.microsoft.com"));
        throw new Exception("Boom");
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果MyCustomCode的实现遇到异常,应用程序会发生什么?

如果不行,考虑到异步/等待是多么普遍,这是否意味着部分方法基本上已经过时了?代码生成系统是否应该停止暴露部分方法以支持事件,或者更好的是仍然在基类中清空受保护的虚拟方法?即

protected virtual Task MyCustomCode(T foo)
{
    return Task.FromResult(0);
}
Run Code Online (Sandbox Code Playgroud)

编辑:好的,所以我已经对代码进行了几次更新.在我写的原始伪代码之后没有得到好评.我认为上面的代码表明async partial void MyPartialMethod肯定存在一个问题,因为对MyCodeGeneratedMethod的调用似乎确实打倒了app域,尽管试图捕获调用.我只是想知道是否有更好的选择,而不是转移到受保护的虚拟基类方法.

Ste*_*ary 7

但是,如果MyCustomCode的实现遇到异常,应用程序会发生什么?

async void方法的语义是直接在SynchronizationContext方法开头的当前异常引发异常.关于这个和其他有趣的事实async void在我的async最佳实践文章中有所涉及.

这是否意味着部分方法基本上已经过时了?

与事件处理程序一样过时.所以,不,不是真的.但是,它们没有更新为允许返回类型Task,因此看起来它们是一种语言功能,没有使用其他语言进行主动更新.

代码生成系统是否应该停止暴露部分方法以支持事件,或者更好的是仍然在基类中清空受保护的虚拟方法?

事件根本不会改变这一点; 他们仍然会实施async void.

如果"钩子"需要是异步的,那么它会改变所有生成的代码,因为它也必须都是异步的.

如果生成的代码需要来自该部分方法的某些结果,并且实现必须执行一些异步工作以生成该结果,则异步部分方法才会起作用.根据我的经验,部分方法在概念上更像是事件,因此async void是可以接受的.