VB.NET中的异步lambda表达式
异步VB.NET中的异步lambda表达式,vb.net,lambda,async-await,Vb.net,Lambda,Async Await,异步Sub如下: Dim f As Func(Of Task) = Async Sub() End Sub 生成编译器错误: 错误BC36670:嵌套子项没有与委托“System.Func(Of System.Threading.Tasks.Task)”兼容的签名 等效C#代码编译良好: Func<Task> f = async () => { }; Func f=async()=>{}; 将Async Sub重写为Asy
Sub
如下:
Dim f As Func(Of Task) = Async Sub()
End Sub
生成编译器错误:
错误BC36670:嵌套子项没有与委托“System.Func(Of System.Threading.Tasks.Task)”兼容的签名
等效C#代码编译良好:
Func<Task> f = async () => { };
Func f=async()=>{};
将Async Sub
重写为Async函数
使代码工作
为什么
Async Sub()
不能转换为返回值为Task
类型的委托类型?VB.NETSub
相当于C#返回void
。async void Foo(){}
和async Task Foo(){}
之间存在差异,您的VB.NET正在执行前者,而您需要后者。正如您所提到的,Async函数
使它工作,因为这样它实际上完成了后者
编辑:更多详细信息:
C#:
async void Foo(){}
异步任务栏(){}
void Baz()
{
物体假人;
dummy=(Action)Foo;//确定
dummy=(Func)Foo;//错误
dummy=(操作)条;//错误
dummy=(Func)条;//确定
}
但是,当使用委托时,这会变得更加混乱,因为Foo
和Bar
的委托等价物看起来是一样的:async()=>{}
唯一的区别是在VB.NET中,代理看起来不一样,因为
Sub
或Function
关键字仍然是语法的一部分。VB.NETFunction
实际上意味着从方法返回一些值。上面的代码中没有返回值,因此lambda-函数实际上应该是lambda-Sub
。你在VB.NET中看到过没有返回语句的Function
吗?@ControlFlow C#等价物返回一个值,该值是一个任务
。该任务的返回是隐式的:您没有return
语句,但确实返回了一些东西。在VB.NET中也是如此。@hvd我认为问题是,虽然C#async
关键字将void
函数的声明转换为Func
,但在VB.NETasync
中,似乎不会将Sub
的声明转换为相同的东西。注意,在C#示例中,我们可以采用()=>{}
(它不返回任何内容,因此对应于VB.NET子)并通过简单地预加异步,将其分配给Func
——类似的过程在VB.NET中似乎不起作用。我想这就是问题所在。@AakashM是的,没错。在返回Task
的异步函数中,不返回Task
,而是返回t
:async Task Foo(){return 1;}
@AakashM:想想C#中的枚举数:当你说IEnumerable M(){yield return 1;}
时,你什么也不返回,而是产生一个整数。不返回整数序列--不返回任何内容--也不生成整数序列--生成整数。编译器负责重写为返回IEnumerable
的方法。异步方法也是如此。如果异步方法返回一个任务
,则返回一个int,编译器将其转换为一个返回任务
的方法。
async void Foo() { }
async Task Bar() { }
void Baz()
{
object dummy;
dummy = (Action) Foo; // OK
dummy = (Func<Task>) Foo; // error
dummy = (Action) Bar; // error
dummy = (Func<Task>) Bar; // OK
}