c# - 将 C# 异步 Lambda 方法分配给作为任务类型的变量

标签 c# vb.net asynchronous task anonymous-function

这在 C# 中可能吗?以下代码产生编译器错误。

HashSet<Task<(string Value, int ToNodeId)>> regionTasks =
  new HashSet<Task<(string Value, int ToNodeId)>>();
foreach (Connection connection in Connections[RegionName])
{
    regionTasks.Add(async () =>
    {        
        string value = await connection.GetValueAsync(Key);
        return (value, connection.ToNode.Id);
    }());
}
C# 编译器提示“错误 CS0149:应为方法名称。”无法推断 lambda 方法的返回类型。
请注意我在 lambda 块关闭后立即通过 () 调用 lambda 方法的技术 {}。这确保了 Task返回,不是 Func .
VB.NET 编译器理解这种语法。我惊讶地发现 VB.NET 编译器胜过 C# 编译器的示例。看我的 An Async Lambda Compiler Error Where VB Outsmarts C#完整故事的博客文章。
Dim regionTasks = New HashSet(Of Task(Of (Value As String, ToNodeId As Integer)))
For Each connection In Connections(RegionName)
    regionTasks.Add(Async Function()
        Dim value = Await connection.GetValueAsync(Key)
        Return (value, connection.ToNode.Id)
    End Function())
Next
VB.NET 编译器理解 End Function()技术。它正确推断 lambda 方法的返回类型是 Function() As Task(Of (Value As String, ToNodeId As Integer))因此调用它会返回 Task(Of (Value As String, ToNodeId As Integer)) .这可分配给 regionTasks多变的。
C# 要求我将 lambda 方法的返回值转换为 Func ,这会产生非常难以辨认的代码。
regionTasks.Add(((Func<Task<(string Values, int ToNodeId)>>)(async () =>
{
    string value = await connection.GetValueAsync(Key);
    return (value, connection.ToNode.Id);
}))());
糟糕的。括号太多了!我在 C# 中能做的最好的事情就是显式声明 Func ,然后立即调用它。
Func<Task<(string Value, int ToNodeId)>> getValueAndToNodeIdAsync = async () =>
{
    string value = await connection.GetValueAsync(Key);
    return (value, connection.ToNode.Id);
};
regionTasks.Add(getValueAndToNodeIdAsync());
有没有人找到更优雅的解决方案?

最佳答案

.NET Standard 2.1 (或某些 .NET Framework 版本,请参阅 compatibility list )可供您使用,您可以将 LINQ 与 ToHashSet 一起使用方法:

var regionTasks = Connections[RegionName]
    .Select(async connection => 
    {        
        string value = await connection.GetValueAsync(Key);
        return (Value: value, ToNodeId: connection.ToNode.Id);
    })
    .ToHashSet();
或者只是初始化 HashSet与相应的 IEnumerable .
UPD
评论中链接的另一种解决方法 answer :
static Func<R> WorkItOut<R>(Func<R> f) { return f; }

foreach (Connection connection in Connections[RegionName])
{
    regionTasks.Add(WorkItOut(async () =>
    {        
        string value = await connection.GetValueAsync(Key);
        return (value, connection.ToNode.Id);
    })());
}

关于c# - 将 C# 异步 Lambda 方法分配给作为任务类型的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62734251/

相关文章:

c# - Full Framework 和 .NET Core 的 xml 架构编译的不同行为

c# - 智能设备项目VS2008中的"Unable to connect to any of the specified MySQL hosts."

c# - 如何访问列表内的类内的变量?

database - 从 Visual Basic 2010 到 MS ACCESS 2007 上的 INSERT INTO 命令出现语法错误

c# - 在 C# 中异步发送电子邮件?

c# - c#的音频库

VB.NET 绝对奇怪的表单加载行为

.net - 使用在 "with" block 内分配的实例的成员会抛出 System.NullReferenceException

javascript - 如何在expressjs路由器中使用Async/Await?

android - 在 GridView 适配器 GetView 方法中使用异步方法