I'm relatively new to C# and I'm trying to replicate an asynchronous call that has already been written in C . This has been a little difficult because while I can easily understand the async/await keywords in C#, I'm stuck on the concept of deferred launch in that language. Here is the original code:
bool runMethod(const cv::Mat& param1,
float& param2,
std::pair<float, float>& param3,
std::pair<int, int>& param4)
{
auto async_lazy{ std::async(std::launch::deferred,
[¶m1, ¶m2, ¶m3, ¶m4]
{
const MyClass ret{ MyClass::getInstance()->Method(param1};
if (ret.status)
{
//Do work...
}
return ret.status;
}) };
return async_lazy.get();
}
It may be relevant to add that the "Method" method being called is not async itself.
I also took a look at the first example on this page, that says a Task<(T)> by itself is async. There also seems to be no use of the await keyword: https://docs.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1?view=net-6.0
Would that example reproduce the functionality of the above code?
CodePudding user response:
If my quick google search was correct then launch::deferred
means lazy evaluation on the calling thread.
In that case, using a task might not be a good idea, they are not meant for lazy evaluation because:
- Awaiting them or taking their result does not start them if they were not started already (and starting them while they are already running throws an exception)
- You can't run them on the calling thread, they represent an asynchronous operation (such as IO) or work running on a ThreadPool thread
- Even if you could run them on the calling thread if they were not started yet, they are typically created using
Task.Run()
orTask.Factory.StartNew()
which starts them right away
Perhaps you could use System.Lazy<T>
instead. It seems to do what you need, including several thread safety options.