Note that there are some explanatory texts on larger screens.

plurals
  1. POTPL FromAsync with TaskScheduler and TaskFactory
    text
    copied!<p>I am trying to create a Task pipeline/ordered scheduler in combination with using <code>TaskFactory.FromAsync</code>.</p> <p>I want to be able to fire off web service requests (using <code>FromAsync</code> to use I/O completion ports) but maintain their order and only have a single one executing at any one time.</p> <p>At the moment I do not use <code>FromAsync</code> so I can do <code>TaskFactory.StartNew(()=&gt;api.DoSyncWebServiceCall())</code> and rely on the <code>OrderedTaskScheduler</code> used by the <code>TaskFactory</code> to ensure that only one request is outstanding.</p> <p>I assumed that this behaviour would stay when using the <code>FromAsync</code> method but it does not:</p> <pre><code>TaskFactory&lt;Stuff&gt; taskFactory = new TaskFactory&lt;Stuff&gt;(new OrderedTaskScheduler()); var t1 = taskFactory.FromAsync((a, s) =&gt; api.beginGetStuff(a, s), a =&gt; api.endGetStuff(a)); var t2 = taskFactory.FromAsync((a, s) =&gt; api.beginGetStuff(a, s), a =&gt; api.endGetStuff(a)); var t3 = taskFactory.FromAsync((a, s) =&gt; api.beginGetStuff(a, s), a =&gt; api.endGetStuff(a)); </code></pre> <p>All of these <code>beginGetStuff</code> methods get called within the <code>FromAsync</code> call (so although they are dispatched in order but there are <code>n</code> api calls occurring at the same time).</p> <p>There is an overload of <code>FromAsync</code> that takes a TaskScheduler:</p> <pre><code>public Task FromAsync( IAsyncResult asyncResult, Action&lt;IAsyncResult&gt; endMethod, TaskCreationOptions creationOptions, TaskScheduler scheduler ) </code></pre> <p>but the docs say:</p> <blockquote> <p>The TaskScheduler that is used to schedule the task that executes the end method.</p> </blockquote> <p>And as you can see, it takes the already constructed <code>IAsyncResult</code>, not a <code>Func&lt;IAsyncResult&gt;</code>.</p> <p>Does this call for a custom <code>FromAsync</code> method or am I missing something? Can anyone suggest where to start on this implementation?</p> <p>Cheers,</p> <p>EDIT:</p> <p>I want to abstract this behaviour away from the caller so, as per the behaviour of <code>TaskFactory</code> (with a specialized <code>TaskScheduler</code>), I need the Task to be returned immediately - this Task will not only encapsulate the <code>FromAsync</code> Task but also the queueing of that task whilst it awaits its turn to execute.</p> <p>One possible solution:</p> <pre><code>class TaskExecutionQueue { private readonly OrderedTaskScheduler _orderedTaskScheduler; private readonly TaskFactory _taskFactory; public TaskExecutionQueue(OrderedTaskScheduler orderedTaskScheduler) { _orderedTaskScheduler = orderedTaskScheduler; _taskFactory = new TaskFactory(orderedTaskScheduler); } public Task&lt;TResult&gt; QueueTask&lt;TResult&gt;(Func&lt;Task&lt;TResult&gt;&gt; taskGenerator) { return _taskFactory.StartNew(taskGenerator).Unwrap(); } } </code></pre> <p>However, this utilizes a thread whilst the <code>FromAsync</code> call is occurring. Ideally I'd not have to do that.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload