Note that there are some explanatory texts on larger screens.

plurals
  1. POAysnc/Await Vs. Task/Continuation UI Control Access
    primarykey
    data
    text
    <p>All, I have a situation where I have been asked to multi-thread a large 'Cost-Crunching' algorithm. I am relatively experienced with <code>Task</code>s and would be confident in adopting a pattern like </p> <pre><code>CancellationTokenSource cancelSource = new CancellationTokenSource(); CancellationToken token = cancelSource.Token; TaskScheduler uiScheduler = TaskScheduler.FromCurrentSynchronizationContext(); Task&lt;bool&gt; asyncTask = null; asyncTask = Task.Factory.StartNew&lt;bool&gt;(() =&gt; SomeMethodAsync(uiScheduler, token, _dynamic), token); asyncTask.ContinueWith(task =&gt; { // For call back, exception handling etc. }, uiScheduler); </code></pre> <p>and then for any operation where I need to provide and UI operation, I would use </p> <pre><code>Task task = Task.Factory.StartNew(() =&gt; { mainForm.progressLeftLabelText = _strProgressLabel; }, CancellationToken.None, TaskCreationOptions.None, uiScheduler); </code></pre> <p>Where this might be wrapped up in a method.</p> <p>Now, I realise that I can make all this much less complicated, and leverage the <code>async/await</code> keywords of .NET 4.5. However, I have some questions: if I have a long running method that I launch using </p> <pre><code>// Start processing asynchroniously. IProgress&lt;CostEngine.ProgressInfo&gt; progressIndicator = new Progress&lt;CostEngine.ProgressInfo&gt;(); cancelSource = new CancellationTokenSource(); CancellationToken token = cancelSource.Token; CostEngine.ScriptProcessor script = new CostEngine.ScriptProcessor(this); await script.ProcessScriptAsync(doc, progressIndicator, token); </code></pre> <p>where <code>CostEngine.ProgressInfo</code> is some basic class used to return progress information and the method <code>ProcessScriptAsync</code> is defined as </p> <pre><code>public async Task ProcessScriptAsync(SSGForm doc, IProgress&lt;ProgressInfo&gt; progressInfo, CancellationToken token, bool bShowCompleted = true) { ... if (!await Task&lt;bool&gt;.Run(() =&gt; TheLongRunningProcess(doc))) return ... } </code></pre> <hr> <p>I have two questions:</p> <ol> <li><p>To get <code>ProcessScriptAsync</code> to return control to the UI <em>almost</em> immediately I await on a new <code>Task&lt;bool&gt;</code> delegate (this seemingly avoids an endless chain of <code>async</code>/<code>await</code>s). <strong>Is this the right way to call <code>ProcessScriptAsync</code>?</strong> ['Lazy Initialisation', by wrapping in an outer method?]</p></li> <li><p>To access the UI from within <code>TheLongRunningProcess</code>, do I merely pass in the UI <code>TaskScheduler</code> <code>uiScheduler</code>; i.e. <code>TheLongRunningProcess(doc, uiScheduler)</code>, then use:</p></li> </ol> <hr> <pre><code>Task task = Task.Factory.StartNew(() =&gt; { mainForm.progressLeftLabelText = _strProgressLabel; }, CancellationToken.None, TaskCreationOptions.None, uiScheduler); </code></pre> <p>as before?</p> <p>Sorry about the length and thanks for your time.</p>
    singulars
    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.
 

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