c#-WPF:无法将异步lambda表达式转换为委托类型';Func<;int>';

c#-WPF:无法将异步lambda表达式转换为委托类型';Func<;int>';,c#,wpf,asynchronous,lambda,C#,Wpf,Asynchronous,Lambda,我试图了解Lambda表达式如何与异步方法一起工作 我有一个函数 private int Server_Get_Int(){ Task<int> task = Task.Factory.StartNew<int>( async () => { FirebaseClient c = Server_Connect(); FirebaseResponse response = awai

我试图了解Lambda表达式如何与异步方法一起工作

我有一个函数

private int Server_Get_Int(){
            Task<int> task = Task.Factory.StartNew<int>( async () => {
                FirebaseClient c = Server_Connect();
                FirebaseResponse response = await c.GetAsync("todos/set");
                return response.ResultAs<int>(); //The response will contain the data being retreived
            } );
            task.Wait();
            int result = task.Result;
            Console.WriteLine(result);
            return result;
        }
private int Server\u Get\u int(){
Task Task=Task.Factory.StartNew(异步()=>{
FirebaseClient c=Server_Connect();
FirebaseResponse=wait c.GetAsync(“todos/set”);
return response.ResultAs();//响应将包含正在检索的数据
} );
task.Wait();
int result=task.result;
控制台写入线(结果);
返回结果;
}
我希望异步代码在lambda表达式中运行,并从服务器返回结果。 但我得到了错误:

 error CS4010: Cannot convert async lambda expression to delegate type 'Func<int>'. An async lambda expression may return void, Task or Task<T>, none of which are convertible to 'Func<int>'.
错误CS4010:无法将异步lambda表达式转换为委托类型“Func”。异步lambda表达式可能返回void、Task或Task,它们都不能转换为“Func”。
它说我只能返回一个空白、任务或任务,据我所知,我正在返回

task<int>
任务
这是我返回的内容的问题还是因为异步lambda

谢谢

编辑:

response.ResultAs()
返回一个Int,但在任务函数中,它应该作为任务返回(控制台应用程序)。这正确显示“结果:10”

static void Main(字符串[]args)
{
Func Func=async()=>{wait Task.Delay(1000);返回10;};
var task=task.Factory.StartNew(func);
task.Wait();
int result=task.Unwrap().result;
写线($“结果:{Result}”);
ReadKey(true);
}
测试代码(控制台应用程序)。这正确显示“结果:10”

static void Main(字符串[]args)
{
Func Func=async()=>{wait Task.Delay(1000);返回10;};
var task=task.Factory.StartNew(func);
task.Wait();
int result=task.Unwrap().result;
写线($“结果:{Result}”);
ReadKey(true);
}

您的整个方法不太理想。您可以将代码重写得更简单。不过,请先对现有代码进行一些注释

  • 您使用的是
    Task.Factory.StartNew()
    ,即。在里面 大多数情况下,您只需使用
    Task.Run()
  • 您正在使用
    Task.Wait()
    Task.Result
    ,在访问它时,这也是
    Task.Result
    Task.Wait()
    。但我想,你想测试lambda,所以这里没问题
  • ResultAs()。方法本身被定义为
    公共虚拟T ResultAs()
    。它不需要返回
    任务
    ,因为lambda是异步的。如果要从lambda中删除
    async
    ,则必须返回一个
    任务
    ,但不能通过简单地将
    ResultAs
    更改为
    ResultAs
    ,必须使用
    TaskCompletionSource

    基于上述情况,我们可以将您的方法改写为:

    private int Server_Get_Int(){
        var task = Task.Run(async () => {
            var c = Server_Connect();
            return (await c.GetAsync("todos/set")).ResultAs<int>();
        });
    
        int result = task.Result;
        Console.WriteLine(result);
        return result;
    }
    
    最后,您似乎还不熟悉使用async/await进行基于任务的编程。我建议你阅读斯蒂芬·克利里(Stephen Cleary)写的(优秀的)文章,然后继续往下读。 async/await的美妙之处在于,它可以通过您的代码自然传播,您可以编写异步代码,就像编写同步代码一样

    另外,在这里放置另一篇文章,介绍为什么不应该使用
    Wait()
    Result
    来简单地获取异步方法的返回值,因为这样会更好地注意到:
    您的整个方法都不太理想。您可以将代码重写得更简单。不过,请先对现有代码进行一些注释

  • 您使用的是
    Task.Factory.StartNew()
    ,即。在里面 大多数情况下,您只需使用
    Task.Run()
  • 您正在使用
    Task.Wait()
    Task.Result
    ,在访问它时,这也是
    Task.Result
    Task.Wait()
    。但我想,你想测试lambda,所以这里没问题
  • ResultAs()。方法本身被定义为
    公共虚拟T ResultAs()
    。它不需要返回
    任务
    ,因为lambda是异步的。如果要从lambda中删除
    async
    ,则必须返回一个
    任务
    ,但不能通过简单地将
    ResultAs
    更改为
    ResultAs
    ,必须使用
    TaskCompletionSource

    基于上述情况,我们可以将您的方法改写为:

    private int Server_Get_Int(){
        var task = Task.Run(async () => {
            var c = Server_Connect();
            return (await c.GetAsync("todos/set")).ResultAs<int>();
        });
    
        int result = task.Result;
        Console.WriteLine(result);
        return result;
    }
    
    最后,您似乎还不熟悉使用async/await进行基于任务的编程。我建议你阅读斯蒂芬·克利里(Stephen Cleary)写的(优秀的)文章,然后继续往下读。 async/await的美妙之处在于,它可以通过您的代码自然传播,您可以编写异步代码,就像编写同步代码一样

    另外,在这里放置另一篇文章,介绍为什么不应该使用
    Wait()
    Result
    来简单地获取异步方法的返回值,因为这样会更好地注意到:

    response.ResultAs()的类型是什么?它返回一个int,但据我所知,当包装在任务中时,它不会作为任务返回吗?不,您应该返回即
    int
    。比如说,你有这样的代码:
    Func=()=>10;Task Task=Task.Factory.StartNew(func);task.Wait();int result=task.result结果变量将为10。我怀疑这是关于
    ResultAs
    方法的问题。它可以连接,但我使用的API没有写太多关于它们生成的函数的内容。但我认为我的问题主要是因为使用异步,大多数问题似乎都是由此产生的。
    response.ResultAs()的类型是什么
    ?它返回一个int,但在包装到任务中时我理解为int
    private int Server_Get_Int(){
        var task = Task.Run(async () => {
            var c = Server_Connect();
            return (await c.GetAsync("todos/set")).ResultAs<int>();
        });
    
        int result = task.Result;
        Console.WriteLine(result);
        return result;
    }
    
    private async Task<int> Server_Get_Int_Async(){
        return await Task.Run(async () => {
            var c = Server_Connect();
            return (await c.GetAsync("todos/set")).ResultAs<int>();
        });
    }
    
    public async Task Foo()
    {
        // This is the fetch task that's going to be completed sometime in the future. You should almost in any case use configure await on your tasks. For reasons see below.
        Task<int> intTask = Server_Get_Int_Async().ConfigureAwait(false);
    
        // Do something other with the task object
    
        // Finally await it and print
        int result = await intTask;
        Console.WriteLine(result);
    }
    
    
    // Do this if you just need the result and nothing else.
    public async Task Bar() 
    {
        int result = await Server_Get_Int_Async().ConfigureAwait(false);
    
       Console.WriteLine(result);
    }