Convert any given function to the expected task

The purpose of the following code is to include any given function in the expected function. The idea is to use it when retrieving data from db, giving the code the flexibility to either use synchronous fetch functions (overlapping my current ORM) or use the same functions as async.

I know that there can be a lot of things wrong with the code concept. At the moment, I was just trying to get rid of compiler errors, so I can run the code and check its behavior. But, of course, I am open to discuss the concept in advance, and if the whole idea behind is not right, use my time more efficiently to find 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; } 
+10
c # task-parallel-library async-await
source share
6 answers

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

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

No need to wrap it in TaskCompletionSource .

I know that there can be many things wrong with the concept of code.

If you are trying to perform an asynchronous query on the database, this solution will definitely not help. This only artificially wraps your result in Task . If you really want to query your database asynchronously, you need to use the asynchronous methods provided by your database provider.

If you are using MySQL and looking for a driver that supports asynchronous mode, look at Dapper

+11
source share

change it to

 int task = await CastFuncToTask<int>(()=>TestFunc(2)); 

In your code, the input provided for CastFuncToTask is int (which returns TestFunc .), But it needs a Func<T> delegate.

+3
source share

my method is this:

 public Task<int> SetOffAsync() { return Task<int>.Factory.StartNew(() => { /*do something else*/ return 42; }); } 

and you can call this:

 int var = await SetOffAsync(); 
+2
source share

In a Windows Forms application, I confirmed that the first call blocks the second. Therefore, the best solution would be to use Task.Run() with a lambda expression.

  private async void button1_Click(object sender, EventArgs e) { button1.Text = "..."; var result = await Task.FromResult(TestFunc(2)); button1.Text = result.ToString(); } private async void button2_Click(object sender, EventArgs e) { button2.Text = "..."; var result = await Task.Run(() => TestFunc(2)); button2.Text = result.ToString(); } private int TestFunc(int x) { System.Threading.Thread.Sleep(5000); return x; } 

The compiler may not know that you do not want to evaluate TestFunc (2), but use it as a delegate and execute the method first, and Task.FromResult simply completes the return value in the Task. This is not what you want.

+1
source share

await Task.Run (() => obj.functionname ());

0
source share

The below code may help others:

Note: GenericMethod is the name of the parameter that we pass as Func with Input (T1) and output (T2) of a common type. Task Factory will provide the necessary access to run your task.

  public async Task<T2> GenericAsyncCall<T1, T2>(Func<T1, T2> GenericMethod, T1 input) { var _output = await Task.Factory.StartNew(() => { var output = GenericMethod.Invoke(input); return output; }); return (T2)_output; } 
0
source share

All Articles