Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert any given function into an awaitable task

The goal of the following code is to cast any given function into an awaitable function. The idea is to use it when fetching the data from the db, giving the code the flexibility to either use the synchronous fetch functions (an imposition of my current ORM), or use the very same functions as async.

I am aware that there could be many things wrong with the concept behind code. By now I was just trying to get rid of the compiler errors so I can run the code and check the behavior. But of course I am open to discuss the concept beforehand, and if the whole idea behind it is wrong then use my time more efficiently looking for another solution.

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;
}
like image 810
Xavier Peña Avatar asked Aug 17 '15 08:08

Xavier Peña


People also ask

How do I create async Task?

You can use await Task. Yield(); in an asynchronous method to force the method to complete asynchronously. Insert it at beginning of your method and it will then return immediately to the caller and complete the rest of the method on another thread.

How do I call a method that returns a function in C#?

If a predefined method returns a Task , you simply mark the calling method as async and put the await keyword in front of the method call. It's helpful to understand the control flow associated with the await keyword, but that's basically it.

Is an async method that returns Task?

Async methods can have the following return types: Task, for an async method that performs an operation but returns no value. Task<TResult>, for an async method that returns a value. void , for an event handler.

How do you call a synchronous method asynchronously in C#?

The simplest way to execute a method asynchronously is to start executing the method by calling the delegate's BeginInvoke method, do some work on the main thread, and then call the delegate's EndInvoke method. EndInvoke might block the calling thread because it does not return until the asynchronous call completes.


1 Answers

Running .NET 4.5, you can greatly simplify your code by doing:

int task = await Task.FromResult(TestFunc(2));

No need to wrap it yourself in a TaskCompletionSource.

I am aware that there could be many things wrong with the concept behind code.

If what you're trying to do is asynchronously query your database, this solution will definitely not help. It only artificially wraps your result in a Task. If you really want to query your database asynchronously, you need to use async methods provided by your database provider.

If you're using MySQL and looking for a driver that supports async, look into Dapper

like image 122
Yuval Itzchakov Avatar answered Sep 19 '22 17:09

Yuval Itzchakov