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.NET
Sub
相当于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.NET
Function
实际上意味着从方法返回一些值。上面的代码中没有返回值,因此lambda-
函数实际上应该是lambda-
Sub
。你在VB.NET中看到过没有返回语句的
Function
吗?@ControlFlow C#等价物返回一个值,该值是一个
任务
。该任务的返回是隐式的:您没有
return
语句,但确实返回了一些东西。在VB.NET中也是如此。@hvd我认为问题是,虽然C#
async
关键字将
void
函数的声明转换为
Func
,但在VB.NET
async
中,似乎不会将
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
}