Is there a good real world example for coroutines - c++-coroutine

Currently I am reading a lot about coroutines.
While I think I only partly understand what they do (Allowing a function to be returned and continued at a certain point for instance), I really don't know why I should use them. I see no real benefit in using a coroutine. For me these things look to me like goto with extra steps. Could someone give me a good real world example where a coroutine might really improve a code base? Maybe that helps me to get the concept.

Coroutines allow us to model cooperative multitasking systems in a very simple and modular way. This kind of systems may suit many problems like multi-agent games, stock market simulators, operating systems, etc.
The simplicity comes from the fact that we may need only two function-like coroutines to express the concept in code. Classes, state structures, function pointers are no longer required. Below is a pseudo-code illustration which defines a scheduler and a task. Unlike normal functions, both instances of task pass the execution to each other after do_one_step call.
void scheduler(list<task> tasks) {
while(true) {
for(t : tasks)
await t;
}
}
void task(int arg) {
while(1) {
do_one_step(arg);
yield;
}
}
void main() { await scheduler( list( { task(0), task(1) } ); }
More importantly, the code for task may now be modular: tasks are allowed to include subtasks, which resemble its structure. Any subtask may be designed as a valid task itself:
void subtask(int arg) {
do_one_step(arg);
yield;
do_one_step(arg);
yield;
}
void task(int arg) {
while(1) {
await subtask(arg);
yield;
}
}
void main() { await scheduler( list({task(0), task(1), subtask(2)}); }
Coroutines allow us to stack subtasks into larger tasks, and provide us with a new tool to modularize our solutions.

Related

Kotlin coroutines running sequentially even with keyword async

Hi guys i'm trying to improve performance of some computation in my system. Basically I want to generate a series of actions based on some data. This doesn't scale well and I want to try doing this in parallel and getting a result after (a bit like how futures work)
I have an interface with a series of implementations that get a collection of actions. And want to call all these in parallel and await the results at the end.
The issue is that, when I view the logs its clearly doing this sequentially and waiting on each action getter before going to the next one. I thought the async would do this asynchronously, but its not.
The method the runBlocking is in, is within a spring transaction. Maybe that has something to do with it.
runBlocking {
val actions = actionsReportGetters.map { actionReportGetter ->
async {
getActions(actionReportGetter, abstractUser)
}
}.awaitAll().flatten()
allActions.addAll(actions)
}
private suspend fun getActions(actionReportGetter: ActionReportGetter, traderUser: TraderUser): List<Action> {
return actionReportGetter.getActions(traderUser)
}
interface ActionReportGetter {
fun getActions(traderUser: TraderUser): List<Action>
}
Looks like you are doing some blocking operation in ActionReportGetter.getActions in a single threaded environment (probably in the main thread).
For such IO operations you should launch your coroutines in Dispatchers.IO which provides a thread pool with multiple threads.
Update your code to this:
async(Dispatchers.IO) { // Switch to IO dispatcher
getActions(actionReportGetter, abstractUser
}
Also getActions need not be a suspending function here. You can remove the suspend modifier from it.

Dart - Async vs Sync performance considerations

Working with async/await is quite contagious and i end up having asynchronous methods all over my code. This makes me wonder : Is there any difference between those calls ? What about performance ?
class SomeClass{}
//Sync return
SomeClass syncMethod(){
return SomeClass();
}
//Immediate async return
Future<SomeClass> asyncMethod() async{
return SomeClass();
}
//Await an immediate async return
Future<SomeClass> otherAsyncMethod() async{
SomeClass someClass = await asyncMethod();
return someClass;
}
Thank you !
Async operations do have an overhead. They create futures, attach listeners to those futures, schedule microtasks, asynchronous complete the futures, etc. All that inevitably takes extra time and space over just returning a value on the stack, and on top of that, you get more latency too because the asynchronous operations might be interleaved with other operations.
An async function like
Future<int> foo(Future<int> bar()) async {
print("before");
var result = await bar();
print("after");
return result;
}
is equivalent to a function written as:
Future<int> foo(Future<int> bar()) {
var $c = Completer<int>();
print("before");
bar().then((int result) {
print("after");
$c.complete(result);
}, onError: (e, s) {
$c.completeError(e, s);
});
return $c.future;
}
The compiler tries to make something like that (but probably not as good as a hand-crafted rewrite). All of that extra future-management is necessary overhead for an asynchronous function.
That's also the advantage of asynchronicity: You can do something else while you are waiting for, fx, I/O operations. Even with the overhead, a properly written asynchronous program can still be done sooner than if all I/O operations were blocking. And sometimes it's not.
If your program does I/O, then unless it's a very specialized program, chances are the I/O time is going to dominate everything else

How to implement kind of global try..finally in TPL?

I have async method that returns Task. From time to time my process is recycling/restarting. Work is interruping in the middle of the Task. Is there more or less general approach in TPL that I can at least log that Task was interruped?
I am hosting in ASP.NET, so I can use IRegisteredObject to cancel tasks with CancellationToken. I do not like this however. I need to pass CancellationToken in all methods and I have many of them.
try..finally in each method does not seem even to raise. ContinueWith also does not work
Any advice?
I have single place I start my async tasks, however each task can have any number of child tasks. To get an idea:
class CommandRunner
{
public Task Execute(object cmd, Func<object, Task> handler)
{
return handler(cmd).ContinueWith(t =>
{
if (t.State = == TaskStatus.Faulted)
{
// Handle faultes, log them
}
else if (x.Status == TaskStatus.RanToCompletion)
{
// Audit
}
})
}
}
Tasks don't just get "interrupted" somehow. They always get completed, faulted or cancelled. There is no global hook to find out about those completions. So the only option to do your logging is to either instrument the bodies of your tasks or hook up continuations for everything.

How to use dispatcher

how to use dispatcher.BeginInvoke in for loop( httpwebrequest).With each dispatcher.BeginInvoke have complete before call another dispatcher.BeginInvoke. Because objects return by httpwerequest are wrong position.
No, BeginInvoke is asynchronous - you're basically adding delegates to a queue of items to be executed on the UI thread.
If you need to wait until the delegate has executed before you continue work in your background thread, you'll need to do a bit of work yourself, as Silverlight doesn't support the synchronous Dispatcher.Invoke method, or the DispatcherOperation.Wait() method. Silverlight tries to avoid synchronous approaches like this - if you can possibly redesign your code so that you don't need to wait, that would be preferable.
Being able to easily convert a synchronous sequence of operations into asynchrounous code has been a subject I've blogged about a fair bit. If you want to take up my approach you will need to add the following (relatively small) chunks of code:
The core AsyncOperationService
Code to create an AsyncOperation from the .NET Async Pattern
A couple of Extension methods for WebRequest
Here is some example code that has the flavour of what you describe in your question:-
IEnumerable<AsyncOperation> LoadSomeStuff(IList<string> urls)
{
for (string url in urls)
{
yield return AsyncOperationService.SwitchToBackgroundThread();
WebRequest req = WebRequest.Create(url);
WebResponse resp = null;
yield return req.GetResponseAsyncOp(r => resp = r);
using (resp)
{
// Do stuff with the Web Response such as construct model class instances from a stream.
}
// When ready to actually start touching the UI
yield return AsyncOperationService.SwitchToUIThread();
// Do stuff to the UI
}
}
usage:
List<string> urls = new List<string> {"pinkElephants.xml", "whileElephants.xml"}
LoadSomeStuff(urls).Run(err =>
{
if (err == null)
{
// Cool, it all worked and I probably don't need to do anything
}
else
{
// Something bad happened, lets tell the user about it in the UI somehow.
}
});
Note that this isn't the most efficient code possible. However in many cases the time it takes HTTP response to be delivered massively out-weighs the time the rest of the code uses up so the inefficiency can be quite small and well worth the reduced complexity of code.

Condition check inside a function or before its call?

Which of these 2 programming styles do you prefer? Why? Are there particular advantages to one over the other?
// Style 1
if (doBorder)
doTheBorder();
if (doFrame)
doTheFrame();
if (doDraw)
doTheDraw();
void doTheBorder()
{
// ...
}
void doTheFrame()
{
// ...
}
void doTheDraw()
{
// ...
}
// Style 2
doTheBorder();
doTheFrame();
doTheDraw();
void doTheBorder()
{
if (!doBorder)
return;
// ...
}
void doTheFrame()
{
if (!doFrame)
return;
// ...
}
void doTheDraw()
{
if (!doDraw)
return;
// ...
}
The first. The second seems to be... lacking in confidence. Why call doTheBorder() if you don't even know if you want the border to be done? IMO, you should assert that the border really needs doing, and then call doTheBorder() with confidence!
...Also, from a more technical point of view: if doTheBorder() is in a closed API, a developer in the distant future might call it and if the second style is employed, they may wonder why the border didn't get done, despite their call to doTheBorder(). Of course, sometimes certain circumstances or restrictions or limitations may dictate that the second style be used, but I'd avoid it when possible.

Resources