将任何给定的函数转换为等待的任务

Xav*_*eña 10 c# task-parallel-library async-await

以下代码的目标是将任何给定的函数转换为等待函数.我们的想法是在从db中获取数据时使用它,使代码可以灵活地使用同步获取函数(强制使用当前的ORM),或者使用与async完全相同的函数.

我知道代码背后的概念可能有很多问题.到目前为止,我只是想摆脱编译器错误,所以我可以运行代码并检查行为.但是我当然愿意事先讨论这个概念,如果它背后的整个想法是错误的,那么就更有效地利用我的时间寻找另一个解决方案.

async static void Main()
{
    // The following line gives a compiler error:
    // Error    1   The best overloaded method match for 'CastFuncToTask<int>(System.Func<int>)' has some invalid arguments 
    int task = await CastFuncToTask<int>(TestFunc(2));
}

private static Task<T> CastFuncToTask<T>(Func<T> func)
{
    TaskCompletionSource<T> taskCompletionSource = new TaskCompletionSource<T>();
    T result = func.Invoke();
    taskCompletionSource.SetResult(result);
    return taskCompletionSource.Task;
}

private static int TestFunc(int testInt) 
{
    return testInt * 2;
}
Run Code Online (Sandbox Code Playgroud)

Yuv*_*kov 12

运行.NET 4.5,您可以通过以下方式大大简化代码:

int task = await Task.FromResult(TestFunc(2));
Run Code Online (Sandbox Code Playgroud)

无需自己包装TaskCompletionSource.

我知道代码背后的概念可能有很多问题.

如果你要做的是异步查询你的数据库,这个解决方案绝对没有帮助.它只是人为地将你的结果包装成一个Task.如果您确实想要异步查询数据库,则需要使用数据库提供程序提供的异步方法.

如果您正在使用MySQL并寻找支持异步的驱动程序,请查看Dapper


小智 5

您可以使用:

await Task.Run(() => obj.functionname());
Run Code Online (Sandbox Code Playgroud)


Tah*_*ooy 2

将其更改为

int task = await CastFuncToTask<int>(()=>TestFunc(2));
Run Code Online (Sandbox Code Playgroud)

在您的代码中,提供的输入CastFuncToTaskint(TestFunc返回的内容。) 但它需要一个 delegate Func<T>