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域,尽管试图捕获调用.我只是想知道是否有更好的选择,而不是转移到受保护的虚拟基类方法.
但是,如果MyCustomCode的实现遇到异常,应用程序会发生什么?
async void方法的语义是直接在SynchronizationContext方法开头的当前异常引发异常.关于这个和其他有趣的事实async void在我的async最佳实践文章中有所涉及.
这是否意味着部分方法基本上已经过时了?
与事件处理程序一样过时.所以,不,不是真的.但是,它们没有更新为允许返回类型Task,因此看起来它们是一种语言功能,没有使用其他语言进行主动更新.
代码生成系统是否应该停止暴露部分方法以支持事件,或者更好的是仍然在基类中清空受保护的虚拟方法?
事件根本不会改变这一点; 他们仍然会实施async void.
如果"钩子"需要是异步的,那么它会改变所有生成的代码,因为它也必须都是异步的.
如果生成的代码需要来自该部分方法的某些结果,并且实现必须执行一些异步工作以生成该结果,则异步部分方法才会起作用.根据我的经验,部分方法在概念上更像是事件,因此async void是可以接受的.
| 归档时间: |
|
| 查看次数: |
952 次 |
| 最近记录: |