Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>TPL already provides the ContinueWith function to execute one task when another finishes. Task chaining is one of the main patterns used in TPL for asynchronous operations.</p> <p>The following method downloads a set of images and continues by renaming each of the files </p> <pre><code>static void DownloadInParallel(string[] urls) { var tempFolder = Path.GetTempPath(); var downloads = from url in urls select Task.Factory.StartNew&lt;string&gt;(() =&gt;{ using (var client = new WebClient()) { var uri = new Uri(url); string file = Path.Combine(tempFolder,uri.Segments.Last()); client.DownloadFile(uri, file); return file; } },TaskCreationOptions.LongRunning|TaskCreationOptions.AttachedToParent) .ContinueWith(t=&gt;{ var filePath = t.Result; File.Move(filePath, filePath + ".test"); },TaskContinuationOptions.ExecuteSynchronously); var results = downloads.ToArray(); Task.WaitAll(results); } </code></pre> <p>You should also check the <a href="http://blogs.msdn.com/b/pfxteam/archive/2010/05/04/10007557.aspx" rel="nofollow noreferrer">WebClient Async Tasks</a> from the ParallelExtensionsExtras samples. The DownloadXXXTask extension methods handle both the creation of tasks and the asynchronous downloading of files.</p> <p>The following method uses the DownloadDataTask extension to get the image's data and rotate it before saving it to disk</p> <pre><code>static void DownloadInParallel2(string[] urls) { var tempFolder = Path.GetTempPath(); var downloads = from url in urls let uri=new Uri(url) let filePath=Path.Combine(tempFolder,uri.Segments.Last()) select new WebClient().DownloadDataTask(uri) .ContinueWith(t=&gt;{ var img = Image.FromStream(new MemoryStream(t.Result)); img.RotateFlip(RotateFlipType.RotateNoneFlipY); img.Save(filePath); },TaskContinuationOptions.ExecuteSynchronously); var results = downloads.ToArray(); Task.WaitAll(results); } </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. 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.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. COTwo things, I don't think TaskContinuationOptions.ExecuteSynchronously does what I need. That "something" (moving files in your example) can't happen at the same time on more than one thread. Let's pretend that instead of moving file it is communicating with a device through a serial cable. Two, like I said there's more to it than what I simplified it to. I don't think it's proper to have the two tasks combined into the same method. But that forces me to pass around Tasks which seems like a bad pattern.
      singulars
    2. COWhat you call a bad pattern is the actual design philosophy of the TPL. It is actually pretty close to F# in this matter. Second, ExecuteSynchronously means that the continuation will run using the same thread as the task that precedes it. Finally, you are NOT combining tasks into the same method. The lambda passed to the task or the continuation is yet another anonymous function. You could easily pass a method name instead of using a lambda. If you find the way TPL works uncomfortable you should probably look to a different library or pattern instead of trying to work against it.
      singulars
    3. COAnd that very well may be the answer. If that's the case you'll get your up vote back and accepted. As to my two points though I think we're having a breakdown of communication. 1) ExecuteSynchronously means that the continuation may be running on SEVERAL threads at the same time. The continuation must ONLY be running on ONE thread at any given time in my situation. 2) I know it's technically its own method and I could drop in a method call as well. But the two things are actually in two completely separate classes that really shouldn't even know about each other. And thus my dilemma.
      singulars
 

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