C# 如何使分部方法异步
我用partial方法生成了一个代码C# 如何使分部方法异步,c#,asynchronous,auto-generate,C#,Asynchronous,Auto Generate,我用partial方法生成了一个代码 { ... partial void InterceptOperationCall(IOperationContext context); ... async Task SomeMethod() { InterceptOperationCall(cntx); await LongOperation(cntx); } } 手写部分 { partial void Inte
{
...
partial void InterceptOperationCall(IOperationContext context);
...
async Task SomeMethod()
{
InterceptOperationCall(cntx);
await LongOperation(cntx);
}
}
手写部分
{
partial void InterceptOperationCall(IOperationContext context)
{
}
}
我需要在InterceptOperationCall
中进行异步调用,有人知道解决部分方法限制的方法吗
另一个词:
我想异步执行InterceptOperationCall,并保证在长时间操作之前执行该操作,同时我想选择在另一个文件中声明该方法的主体
UPD作为解决方案,我选择:
- 不使用生成的部分方法存根,并使用动态代理(
)包装并使用Castle.DynamicProxy
from(AsyncInterceptorBase
)Nito.AsyncEx
- 我看到的另一个选项是重写代码生成器
我一直在寻找更好的解决方案,如果有人知道另一种方法来提供可选功能,使用somoe异步逻辑包装异步调用,请帮助我。在实现分部方法时,可以使用async关键字 所以
应该没有问题。我看不到一种方法可以避免async void的所有缺点(正如Peter Schneider评论中链接的Stephen Cleary文章中所讨论的)
我认为,如果您无法找到或编写所讨论的异步API的同步版本,最好的办法是调用异步方法,然后使用task.Wait()等待完成。如果有多个异步调用,请使用ContinueWith组合它们。基本上,您需要使用.Net 4.0样式的任务库。部分方法就像接口一样。他们是合同。任何实现分部方法的人,就像接口方法一样,都在履行该契约。在这种情况下,方法的契约是一个同步方法。没有办法拥有异步实现,因为该方法的正确异步实现需要方法的调用方知道它是一个异步方法,并相应地采取行动。由于调用方将契约编写为同步方法,因此不会发生这种情况 因此,您的解决方案是将方法的契约更改为异步的,这意味着更改分部方法的声明,或者提供同步而不是异步的实现
我认为第三种选择是让接口(在本例中是partial方法)同时支持这两种方法。有两个部分方法,一个异步,一个同步,让实现提供他们想要的任何一个。你能安全地建议
async void
而不知道相关代码的上下文(不是双关语)吗?不。。。我认为用户不知道如何连接自动生成方法的异步实现。然而,还是有一些需要注意的事情…@PeterSchneider,太好了!它将编译并工作,但方法InterceptOperationCall、LongOperation的执行顺序取决于竞争条件。你知道什么方法可以让这个构造成为可以等待的吗?@gabba当然,你返回的是async Task
,而不是async void(现在你看到了分部类和异步方法的问题)。您可能需要重新考虑您的设计,不再使用分部类。@ScottChamberlain,我不得不使用分部,因为需要使用现有的代码,您能用async Task解释一下您的想法吗?如果您想了解async分部方法的限制,可以在文档中找到它们。但是,如果您需要绕过部分方法限制,您需要提供更多信息。@Llazar,谢谢您的关注,我添加了一些问题的细节,您能告诉我您需要什么信息吗?@gabba您是希望能够等待部分方法,还是希望能够使用部分方法调用等待函数?所示示例是一个void
方法,因此我要求澄清。如果重写codegenerator是一个选项,那么我建议将其重写为更符合async await API。@Nkosi,您能提供一些示例或想法吗?您能提供部分异步方法的示例吗?或者给我举个例子?@gabba它只会有任何其他异步方法的签名。它将返回一个任务
,或者使用较旧的编码方式,接受回调,或者使用其他方式通知调用者它已完成。但现在它通常只返回一个任务
。据我所知,部分方法无法返回值。分部方法必须为void。@然后它必须接受回调或其他形式的异步,这些异步可以作为参数传递,而不是由方法返回。
async partial void InterceptOperationCall(IOperationContext context) {
}