There was a need to call a async method in my code synchronously.
All the various documented ways of calling it synchronously were failing.. I was struggling badly..
and finally stumbled into a piece of code which finally worked.. i will document all the failed and then the successful attempts..
Lets say, I have the following methods to be called
private void DoSomethingAsync(string text)
{
////some code here.....
}
private async Task DoSomethingAndReturnSomethingAsync(string text)
{
////some code here.....
return "something something";
}
The various methods that I used to make the asynchrous from my API controller code are as follows:
====================
Attempt 1:========================================
private void WriteToLog(string text)
{
Task task = DoSomethingAsync(text);
task.Wait();
}
This looks correct, but it does not work. The whole program freezes forever.
====================
Attempt 2:========================================
Hmm.. Maybe the task was not started?
private void WriteToLog(string text)
{
Task task = DoSomethingAsync(text);
task.Start();
task.Wait();
}
This throws InvalidOperationException: Start may not be called on a promise-style task.
====================
Attempt 3:========================================
Hmm.. Task.RunSynchronously sounds promising.
private void WriteToLog(string text)
{
Task task = DoSomethingAsync(text);
task.RunSynchronously();
}
This throws InvalidOperationException: RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method.
====================
Attempt 4:========================================
Used the most commonly prescribed procedure advocated in the net, i.e., to use the .reslt property of the Task object, which effective blocks the call and makes it synchronous
private void WriteToLog(string text)
{
MyClass myObj = await DoSomethingAsync(text).result;
or,
Task task await DoSomethingAsync(text);
MyClass myObj = task.result;
}
It too does not work. The whole program freezes forever like the .wait call().
====================
Attempt 5:========================================
Next I used another oft recommended method in the net
private void WriteToLog(string text)
{
MyClass myObj = DoSomethingAsync(text).GetAwaiter().GetResult();
}
Unfortunately it resulted in the same, the code was unresponsive for a long time.
Looking at the methods, I believe they are just wrappers to the wait() method and the Result Property, and hence behaved no different than them.
====================
Attempt 6:========================================
private void WriteToLog(string text)
{
var task = Task.Run(async () => { await DoSomethingAsync(text); });
task.Wait();
}
This was the final piece which finally worked...
Also, for receiving value back from the async method I used the following, a little variation of the same code..
private void WriteToLog(string text)
{
var result = Task.Run(async () => { return await DoSomethingAndReturnSomethingAsync(text); }).Result;
}
====================================================================