Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You seem to have several goals/questions here:</p> <ol> <li><em>Remove earlier changes that are no longer needed because of later changes.</em> A linked list could be a good fit for this. It provides good performance for both general queue usage and good item removal performance.</li> <li><em>Cancellation of in-progress operations that are no longer needed because of later changes.</em> This would also include operations that need to be restarted. This will require you to find a library that allows you to cancel in-progress operations. The System.IO classes do not provide such cancellation, so you will need to either find a library or roll your own.</li> <li><em>Could this be a use case for the Task Parallel Library or is there some Reactive approach that I could take?</em> Your phrasing struck me as if there is a one or the other choice here, but there's no reason you can't mix the two together. The observable you should for the file changes is a good starting point (RX). The in-progress operations would likely be implemented as methods taking a <code>CancellationToken</code> and returning a <code>Task</code> (TPL).</li> </ol> <p>The missing step here seems to be how to go from a "queue" of changes to actual work. Basically, the subscription must queue the change (quickly) and launch a (slow, async) method, if it is not already running, that "recursively" processes the queue; something like:</p> <pre class="lang-vb prettyprint-override"><code>'changes is your returned observable 'toProcess is the "queue" of changes 'processor holds information about and the task of the in-progress operation changes.Subscribe(Sub(c) UpdateQueueWithChange(c, toProcess, processor) If processor.Task.IsCompleted Then ProcessNextChange(processor, toProcess) End If End Sub) </code></pre> <p><code>ProcessNextChange</code> is a method that will get the next change in the queue, start the operation, set the callback for the operation task to re-call ProcessNextChange. If no changes are left, <code>processor</code> should be given a completed task that does not re-call ProcessNextChange.</p> <p><code>UpdateQueueWithChange</code> will need to update the "queue" and cancel the in-progress operation if necessary, which should trigger a call to <code>ProcessNextChange</code> due to task completion that will start the next operation.</p> <p>If you want to cancel the operations when you cancel the subscription to the changes observable, I would recommend putting the subscription disposable into a <code>CompositeDisposable</code> along with a <code>SerialDisposable</code> that would store a <code>CancellationDispoable</code> (updated by <code>ProcessNextChange</code> and stored additionally in <code>processor</code>) that is the source of the <code>CancellationToken</code> needed by the operation methods. ProcessNextChange would check the SerialDisposable to see if it had been disposed before launching an operation. The CompositeDisposable would be what you store somewhere to end the whole thing.</p> <pre class="lang-vb prettyprint-override"><code>CompositeDisposable 'this is what your application keeps around |- IDisposable from subscription to changes observable |- SerialDisposable |- .Disposable property = CancellationDisposable 'changed each time ProcessNextChange is called </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

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