30

I have WCF connector that should get some small amount of data for me, usually it takes up to 20 seconds to get this data for each item ( which is fine ). I want to use Task to get data for me and then add WinForm controls with value from this Tasks.

I've created list of objects which will consist this data.

Used first Task as the one which updates the list and i want Task that is right away after first Task is done to create controls.

This is the code so far:

List<IpVersionCounter> ipVersionCounters = new List<IpVersionCounter>();
Task task = Task.Factory.StartNew(() =>
{
   foreach (var sitein settings.Sites)
   {
       string ip = site.ip;
       string version = "undefined";

       using (WcfConnector wcfConnector = 
                    WcfConnector.CreateConnectorWithoutException((ip)))
       {
           if (wcfConnector != null)
           {
               version= string.Format("{0} {1} {2}", 
               wcfConnector.VersionController.GetBranchName(), 
               wcfConnector.VersionController.GetBuildNumber(),
               wcfConnector.VersionController.GetCurrentVersion());
           }
       }
       counter++;
       ipVersionCounters.Add(new IpVersionCounter
                            {
                            Ip = ip,
                            Version = Version,
                            Counter = counter
                            });
    }
return ipVersionCounters;
}).ContinueWith();

AddProgressBar(ipVersionCounter);

I don't know if i'm going right way and how to use ContinueWith to pass value from first method to second.

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
eugeneK
  • 10,750
  • 19
  • 66
  • 101

1 Answers1

56

In the example below previousTask references the previous task, use the Result property to get the return value from it.

Task task = Task.Factory.StartNew(() =>
{
   // Background work
   return ipVersionCounters;
}).ContinueWith((previousTask) => 
{
   var ipVersionCounters = previousTask.Result;
});

Update

If you want the continuewith to execute on the UI thread use (If you are starting on the UI thread) ...

Task.Factory.StartNew(() =>
{
  // Background work
}).ContinueWith((previousTask) => {
  // Update UI thread
}, TaskScheduler.FromCurrentSynchronizationContext());

(which was taken from this answer for more info)

PaulB
  • 23,264
  • 14
  • 56
  • 75
  • I get: Cross-thread operation not valid: Control 'xPanel' accessed from a thread other than the thread it was created on. I guess i cannot add controls to this thread from other thread is there a way to ? – eugeneK Oct 27 '11 at 07:21
  • 6
    You have to do UI operations on the UI thread. You can call [TaskScheduler.FromCurrentSynchronizationContext](http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.fromcurrentsynchronizationcontext.aspx) to obtain a scheduler that executes your tasks on the UI thread. [Task.ContinueWith](http://msdn.microsoft.com/en-us/library/dd321307.aspx) accepts such a scheduler. – Andreas Oct 27 '11 at 07:27