I have gone through several post for converting existing synchronous method to asynchronous. So based on what I have read I am converting the synchronous method to asynchronous like below
Synchronous
public class SomeClass
{
public int DoWork()
{
return DoLongRunningWork();
}
public int DoLongRunningWork()
{
Thread.Sleep(1000);
return 1;
}
}
I converted this to Asynchronous version like below
public class SomeClass
{
public async Task<int> DoWorkAsync()
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
return await DoLongRunningWorkAsync();
}
public Task<int> DoLongRunningWorkAsync()
{
Thread.Sleep(1000);
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
return Task.Run(() => 1);
}
}
I am calling this from Main() Method
static void Main()
{
Someclass worker = new SomeClass();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
var result = worker.DoWorkAsync().GetAwaiter().GetResult();
Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
Console.WriteLine(result);
Console.ReadKey();
}
- Is this a correct way to convert synchronous to asynchronous method?
- I was expecting Main method's
ManagedThreadId
will be different thanDoWorkAsync
andDoLongRunningWorkAsync
method'sManagedThreadId
. But they are same, why?
I used Thread.Sleep()
just to simulate the long running method. As per the suggestions below i should have used Task.Delay()
to avoid any confusion.
I dont think i have to put my actual business logic here to understand the concept of async.
As per Stephen Cleary
1> Identify the naturally-asynchronous operations your code is doing.
2>Change the lowest-level API calls to invoke asynchronous APIs (with await) instead of synchronous APIs.
However none of the .Net Libarary methods im using inside LongRunningMethod
are naturally-asynchronous or awaitable and also LongRunningMethod
is not doing any I/O operation.
Requirement
I have Web API which takes JSON string as input. The JSON needs to be transformed into some C# object. For transformation I am building a C# library which takes JSON string as input and then Transform that JSON string into C# objects based on some rules. The library may take time ( few milliseconds) for Transformation, during this I DO NOT want Web API's main thread to block. The main thread should be free to take any other request while the transformation is going on background thread (some other thread).
public class MyWebApi: ApiController
{
private ILib _myLibrary
public MyWebApi(ILib myLibrary)
{
_myLibrary = myLibrary
}
publi async Task<SomeObject> Transform(string jsonString)
{
// i want to make LongRunningMethod() method awaitable
// or at least it needs to execute on different thread so that
// main thread will be free.
var result = await _myLibrary.LongRunningMethod(jsonString);
return result;
}
}
publi class MyLibrary:ILib
{
// A method that does Transformation
public async Task<SomeObject> LongRunningMethod(string jsonString)
{
var result = new SomeObject();
// parse jsonString here
// and based on some complex rules create SomeObject
// this operation may takes time (lets say few milliseconds)
// i may call some other private methods here or public methods from other library
return result
}
}