带参数的异步lambda表达式

tvr*_*tvr 3 c# async-await

我试图从包装器调用我的异步函数.但是我收到了这个编译错误.在下面的代码中,我希望获得string x大部分等待抽象/推送到CallAsyncFunc代码中的值.在c#4.5中执行此操作的正确方法是什么?谢谢!

错误CS4010:无法将异步lambda表达式转换为委托类型' System.Func<int,string>'.异步lambda表达式可能会返回void, Task或者Task<T>没有一个可以转换为' System.Func<int,string>'.

public async Task<T2> CallAsyncFunc<T1,T2>(T1 a, Func<T1, T2> func)
{
    return func.Invoke(a);
}

public async Task<string> GetString(int value)
{
    await Task.Run(() => Thread.Sleep(2000));
    return "" + value;
}

public async Task MainAsyncEntry()
{
    string x = await CallAsyncFunc<int, string>(30, async(x) => await GetString(x));
}
Run Code Online (Sandbox Code Playgroud)

Ora*_*ace 6

在:

string x = await CallAsyncFunc<int, string>(30, async(x) => await GetString(x));
Run Code Online (Sandbox Code Playgroud)

你有两个x第一个问题.尝试:

string y = await CallAsyncFunc<int, string>(30, async(x) => await GetString(x));
Run Code Online (Sandbox Code Playgroud)

这里lambda的输出是string因为你使用async它应该是一个TaskTask<T>.

你可以写:

string y = await CallAsyncFunc<int, string>(30, x => GetString(x).Result);
// Equivalent to
string y = await CallAsyncFunc(30, x => GetString(x).Result);
Run Code Online (Sandbox Code Playgroud)

要么

string y = await CallAsyncFunc<int, Task<string>>(30, x => GetString(x)).Result;
// Equivalent to
string y = await CallAsyncFunc(30, GetString).Result;
Run Code Online (Sandbox Code Playgroud)

但在任何一种情况下,您的CallAsyncFunc同步都会运行,因为它不包含任何内容await.

这是做这件事的好方法:

// This
public async Task<TOut> CallAsyncFunc<TIn, TOut>(TIn input, Func<TIn, Task<TOut>> func)
{
    return await func.Invoke(input);
}

// Or those
public Task<TOut> CallAsyncFunc<TIn, TOut>(TIn input, Func<TIn, Task<TOut>> func)
{
    return func.Invoke(input);
}

public async Task<string> GetString(int value)
{
    await Task.Run(() => Thread.Sleep(2000));
    return value.ToString(CultureInfo.InvariantCulture);
}

public async Task MainAsyncEntry()
{
    string y = await CallAsyncFunc(30, GetString);
}
Run Code Online (Sandbox Code Playgroud)