www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Idiomatic async programming like C# async/await

reply "Cliff" <cliff.s.hudson gmail.com> writes:
(New to D, old hand at software engineering...)

I come from .NET and have made heavy use of the async/await 
programming paradigm there.  In particular, the Task mechanism 
(futures/promises) lets one encapsulate the future result of some 
work and pass that around.  D seems to have something similar in 
std.parallelism.Task, but this seems to additionally encapsulate 
and expose the actual work to do.

What I want to do is be able to define an interface that performs 
certain possibly-slow operations and presents a Task-based 
interface.  Example in C#:

interface MyStore
{
     Task<Key> Store(byte[] content);
     Task<byte[]> Retrieve(Key key);
}

What I feel like I *want* to do in D is something roughly similar:

interface MyDStore
{
     Task!Key Store(InputRange!ubyte content);
     Task!(InputRange!ubyte) Retrieve(Key key);
}

...but std.parallelism.Task requires parameterization on the 
function which the task would execute - that is clearly an 
implementation detail of the store.

What is the correct D idiom to use in this case?
Sep 11 2014
next sibling parent reply "Kagamin" <spam here.lot> writes:
async/await is not so much about futures/promises, but 
optimization of IO-bound operations, i.e. when you wait on 
network/disk, you don't consume stack, threads and similar 
resources, an analog in D is vibe.d
Sep 12 2014
parent reply "Cliff" <cliff.s.hudson gmail.com> writes:
On Friday, 12 September 2014 at 07:15:33 UTC, Kagamin wrote:
 async/await is not so much about futures/promises, but 
 optimization of IO-bound operations, i.e. when you wait on 
 network/disk, you don't consume stack, threads and similar 
 resources, an analog in D is vibe.d
I should have been more clear - it's not the async/await bit I am interested in so much as the Task behavior - that I have some object which represents the (future) completed state of a task without the recipient of that object having to know what the type of the task function is as they are only interested in the task result. I'll take a closer look at vibe.d and see if they already have a system representing this before I cook up my own.
Sep 12 2014
parent "Kagamin" <spam here.lot> writes:
No, vibe provides synchronous non-blocking interface similar to 
async/await.
Sep 13 2014
prev sibling parent reply "Kagamin" <spam here.lot> writes:
On Friday, 12 September 2014 at 03:59:58 UTC, Cliff wrote:
 ...but std.parallelism.Task requires parameterization on the 
 function which the task would execute - that is clearly an 
 implementation detail of the store.
I think, you can wrap the Task in a class. abstract class CTask { abstract void wait(); } abstract class CTask(TResult) { abstract TResult result(); } class CTTask(TTask): CTask(TResult) { TTask task; //std.parallelism.Task override void wait(){ ... } override TResult result(){ ... } }
Sep 14 2014
parent "Cliff" <cliff.s.hudson gmail.com> writes:
On Sunday, 14 September 2014 at 09:19:11 UTC, Kagamin wrote:
 On Friday, 12 September 2014 at 03:59:58 UTC, Cliff wrote:
 ...but std.parallelism.Task requires parameterization on the 
 function which the task would execute - that is clearly an 
 implementation detail of the store.
I think, you can wrap the Task in a class. abstract class CTask { abstract void wait(); } abstract class CTask(TResult) { abstract TResult result(); } class CTTask(TTask): CTask(TResult) { TTask task; //std.parallelism.Task override void wait(){ ... } override TResult result(){ ... } }
Yep, that's what I figured. Thanks :)
Sep 14 2014