Task.ContinueWith not working how I expected

Consider the following code. I am starting with a task that does nothing, and then using ContinueWith() to start 10 calls to a method that increments a counter.

When I run this program, it prints "0", indicating that the increment() method hasn't been called at all. I was expecting it to be called 10 times, since that's how many times I called ContinueWith().

If I uncomment the "Thread.Sleep(20)" line, then it prints "10" as expected.

This happens in either release or debug mode. My system is a core 2 quad with hyperthreading (8 logical cores) running Windows 7 x64.

I assume I have some kind of fundamental misunderstanding about how Task.ContinueWith() works....

using System; using System.Threading; using System.Threading.Tasks; namespace ConsoleApplication4 { class Program { static void Main() { using (var task = Task.Factory.StartNew(()=>{})) { for (int i = 0; i < 10; ++i) { task.ContinueWith(_=> increment()); // Thread.Sleep(20); // Uncomment to print 10 instead of 0. } task.Wait(); } // This prints 0 UNLESS you uncomment the sleep above. Console.WriteLine(counter); } static void increment() { Interlocked.Increment(ref counter); } private static int counter; } }

Can anyone shed any light on what's going on here?

-------------Problems Reply------------

The reason is simple: You wait on the task that is already finished. What you really want is to wait for the ten tasks you created in the loop:

var tasks = new List<Task>();
for (int i = 0; i < 10; ++i)
{
tasks.Add(task.ContinueWith(_=> increment()));
}

Task.WaitAll(tasks.ToArray());

Sure. You're printing out the value when the initial task has completed - you're not waiting for the continuation to occur. In other words, when the initial task completes, 11 things happen:

  • 10 new tasks start executing, each incrementing the counter
  • You print out the counter

You could effectively chain all these together if you want:

task = task.ContinueWith(_=> increment());

Then when the original task finishes, one incrementer will fire. When that finishes, the next incrementer will fire. When that finishes [...]. And when the final incrementer has finished, your Wait call will return.

If you change the main body as follows:

using (var task = Task.Factory.StartNew(() => { }))
{
var t = task;
for (int i = 0; i < 10; ++i)
{
t = t.ContinueWith(_ => increment());
// Thread.Sleep(20); // Uncomment to print 10 instead of 0.
}

t.Wait();
}

You will get 10 without sleeping. The main change is t = t.ContinueWith(...) and t is necessary because you're not allowed to change the using() variable.

Category:c# Views:0 Time:2011-08-09
Tags: task

Related post

  • C# Task.ContinueWith issues 2010-10-28

    I would like to use the Task framework in .NET to schedule something to run on a different thread then when it's done continue with an operation to update the UI on the UI thread. (I haven't played with it much yet, so it's not very familiar to me.)

  • MsTest with Task.ContinueWith() and Task.Wait()-? 2012-03-08

    I'm still in .NET 4.0 and I was wondering whether this pattern will hold up well in various kinds of async unit testing situations: /// <summary> /// Noaa weather test: should read remote XML. /// </summary> [TestMethod] public void Shoul

  • Is there an equivalent of the Task.ContinueWith operator in Rx? 2011-07-19

    Is there an equivalent of the Task.ContinueWith operator in Rx? I'm using Rx with Silverlight, I am making two webservice calls with the FromAsyncPattern method, and I'd like to do them synchronously. var o1 = Observable.FromAsyncPattern<int, stri

  • Creating a execution queue by using Task.ContinueWith? 2011-07-21

    I have several actions that I want to execute in the background, but they have to be executed synchronously one after the other. I was wondering if it's a good idea to use the Task.ContinueWith method to achieve this. Do you foresee any problems with

  • Multiple Parallel Task.ContinueWith order of execution 2010-11-19

    Question This is probably something simple I've missed. Let's say I do (in loveley VB): Dim t1 As New Task(Sub() Debug.WriteLine("t1")) Dim t2 As Task = t1.ContinueWith(Sub() Debug.WriteLine("t2")) Dim t3 As Task = t1.ContinueWith(Sub() Debug.WriteLi

  • .NET 4.0 Tasks: Rethrow Exception to UI Thread in Task.ContinueWith 2011-08-04

    I have a WPF application, where I make a long-running WCF call using the System.Threading.Tasks. I catch unhandled exceptions by adding a handler to Application.Current.DispatcherUnhandledException. I create a task, where the ContinueWith function ru

  • Task ContinueWith causing cross-thread exception despite UI context 2011-09-06

    I was under the impression that using Task's ContinueWith method with a UI context allows performing operations on UI elements without causing a cross-thread exception. However, I am still getting an exception when running the following code: var con

  • Why does TaskFactory.StartNew in combination with Task.ContinueWith work? 2011-10-26

    TaskFactory.StartNew() creates a new Task, starts it and then returns it. I suppose that it is safe to assume that the following code will always work (since it was taken from MSDN): Task.Factory.StartNew(() => Console.WriteLine("first")) .Continu

  • Task.ContinueWith and .wait(). ObjectDisposedException? 2011-11-18

    I use a pattern including tasks in C# where I do Task.Factory.StartNew( .something... ) .ContinueWith(t=> { try{ t.Wait() } catch(Exception ex) ... }); if something forexample includes WCF code or other exception throwing stuff. That way Im sure t

  • Task / Flagged Items not displaying as expected 2014-09-27

    Using the latest version of Outlook 2011 on OSX Mavericks 10.9.2 linked to a Exchange Server. On my iPad and iPhone using the TaskTask App all my Tasks and Flagged items display correctly as they are using OWA. In Outlook 2011 there are flagged messa

  • ui task not acting as expected 2010-06-30

    In the code below, I would like to display a status message while fetching some data before and not display a dialog populated with that data until the data fetch is complete. But the dialog is instead being displayed before the data gets there. What

  • Is it safe to call the ContinueWith method on a TaskCompletionSource.Task (that has had it's .SetResult called)? 2011-09-15

    Is it safe to use the ContinueWith(...) method on a TaskCompletionSource.Task if the TaskCompletionSource.SetResult(...) has already been called? This basic code will hopefully help to frame the question: // this was written inside the question box,

  • Task.Wait() doesn't include any chained (ContinueWith) tasks 2011-11-29

    If you have Private Shared Sub msg(Optional message As String = "") Debug.WriteLine(Threading.Thread.CurrentThread.ManagedThreadId & " " & message) End Sub <TestMethod()> Public Sub TestMethod1() Dim cancel As New Threading.Cancellation

  • WPF + Tasks + WCF = No SynchronizationContext? 2011-02-18

    I have a WPF application that is using System.Threading.Tasks to call a WCF service in the background. I'm using Task.ContinueWith to return the results of the service call to the WPF UI thread. My issue is that, although the continuation does run on

  • Am I responsible for cleaning up after a Task created with the TaskCreationOptions.LongRunning flag? 2011-10-13

    When you create a Task while specifying TaskCreationOptions.LongRunning a new thread is created specifically for the task. If you do not specify the TaskCreationOptions.LongRunning then the threadpool is used. Please correct me if I'm wrong but if th

  • Use !Task.IsCompleted to show user current progress in GUI 2011-11-23

    I have a task that might take a while to complete. I have tried a simple demo but it locks up the GUI thread for some reason. I thought the task would be asynchronous and the GUI would update whilst the task is running. Is this possible with a Task?

  • Using the .NET 4 Task library to display a blocking message box in WPF 2012-01-19

    I have the following code in my WPF application: Task task = Task.Factory.StartNew(() => { DoInitialProcess(); }); task.ContinueWith(t => Dispatcher.BeginInvoke((Action)(() => { MessageBox.Show("Error: " + t.Exception.InnerExceptions[0].Mess

  • C# tasks(with or without TaskContinuationOptions.ExecuteSynchronously) performance vs thread loop , .net threading is worse? 2012-03-07

    i was thinking about the best technique of work when processing queue of actions (the order of operation was important so every operation must come after it's previous one) i'm pretty disappointed from the performance results of running a Task with c

  • Limiting the amount of concurrent tasks in .NET 4.5 2013-12-03

    Observer the following function: public Task RunInOrderAsync<TTaskSeed>(IEnumerable<TTaskSeed> taskSeedGenerator, CreateTaskDelegate<TTaskSeed> createTask, OnTaskErrorDelegate<TTaskSeed> onError = null, OnTaskSuccessDelegate

Copyright (C) dskims.com, All Rights Reserved.

processed in 0.188 (s). 11 q(s)