Answered Problem with Task synchronization

  • Saturday, February 04, 2012 5:23 AM
     
      Has Code

    I'm having a problem getting task synchronization to work.  In the following test program, the first 5 second delay never happens and the detail field is not cleared before the second sleep (the dialog just immediately shows the stage of 3 and the incremented value of 500 and then waits the 3 seconds and then hides the dialog.  Any ideas what i'm doing wrong here?  Thanks!

    	public partial class MainWindow : Window
    	{
    		private ProgressDlg dlgProgress;
    		private int ProgressCount = 0;
    
    		public MainWindow()
    		{
    			InitializeComponent();
    		}
    
    		static int rcnt = 0;
    		private void OnClickTest(object sender, RoutedEventArgs e)
    		{
    			++rcnt;
    			string strTest = "Testing LeftDir" + rcnt.ToString();
    			LWDMSettings.Instance.LeftDir = strTest;
    			strTest = "Testing RightDir" + rcnt.ToString();
    			LWDMSettings.Instance.RightDir = strTest;
    			LWDMSettings.Instance.ProgressStage = "Showing the progress stage";
    			LWDMSettings.Instance.ProgressDetails = "";
    			dlgProgress.Show();
    			Task.Factory.StartNew(() =>
    			{
    				TestTask1();
    			});
    		}
    
    		private void OnLoaded(object sender, RoutedEventArgs e)
    		{
    			dlgProgress = new ProgressDlg();
    			dlgProgress.Owner = this;
    		}
    
    		private void TestTask1()
    		{
    			ProgressCount = 0;
    			LWDMSettings.Instance.ProgressStage = "Beginning TestTasks2";
    			LWDMSettings.Instance.ProgressDetails = "";
    			List<Task> tasks = new List<Task>();
    			var t = Task.Factory.StartNew(() =>
    			{
    				TestTask2();
    			});
    			tasks.Add(t);
    			t = Task.Factory.StartNew(() =>
    			{
    				TestTask2();
    			});
    			tasks.Add(t);
    			Task.Factory.ContinueWhenAll(tasks.ToArray(),
    				   result0 =>
    				   {
    					   Thread.Sleep(5000);
    				   });
    			tasks.Clear();
    			LWDMSettings.Instance.ProgressStage = "Beginning TestTasks3";
    			LWDMSettings.Instance.ProgressDetails = "";
    			t = Task.Factory.StartNew(() =>
    			{
    				TestTask3();
    			});
    			tasks.Add(t);
    			t = Task.Factory.StartNew(() =>
    			{
    				TestTask3();
    			});
    			tasks.Add(t);
    			Task.Factory.ContinueWhenAll(tasks.ToArray(),
    				   result1 =>
    				   {
    					   Thread.Sleep(3000);
    					   this.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
    					   {
    						   dlgProgress.Hide();
    					   }));
    				   });
    		}
    
    		private void TestTask2()
    		{
    			for (int i = 0; i < 250; i++)
    			{
    				Interlocked.Increment(ref ProgressCount);
    				if (ProgressCount % 50 == 0)
    				{
    					LWDMSettings.Instance.ProgressDetails = String.Format("Incremented value is {0}", ProgressCount);
    				}
    			}
    		}
    
    		private void TestTask3()
    		{
    		}
    	}
    
    

Answers

All Replies

  • Saturday, February 04, 2012 11:59 AM
     
      Has Code

    Hiya

     

    I may be mistaken, but the first thing I notice is you're reusing the t object, when you should be creating a new one.

     

    			var t = Task.Factory.StartNew(() =>
    			{
    				TestTask2();
    			});
    			tasks.Add(t);
    			t = Task.Factory.StartNew(() =>
    			{
    				TestTask2();
    			});
    			tasks.Add(t);
    

     

    I think this should be:

     

     

    			var t = Task.Factory.StartNew(() =>
    			{
    				TestTask2();
    			});
    			tasks.Add(t);
    			var t2 = Task.Factory.StartNew(() =>
    			{
    				TestTask2();
    			});
    			tasks.Add(t2);
    

     

    There may be something else but I don't have time right now to recreate your example.

     

    Best regards,
    Pedro


    If you find my post helpful, please remember to "Mark As Answer" and/or "Vote as Helpful"

    • Edited by XAML guy Saturday, February 04, 2012 12:05 PM
    •  
  • Saturday, February 04, 2012 6:05 PM
     
     
    Okay, I made those changes but it still doesn't work.  I could zip up my project if there were a way to post/send it to you?
  • Sunday, February 05, 2012 10:41 PM
     
     
    I think I see my problem.  I was looking at the ContinueWhenAll as similar to the MFC WaitForAll which would block until all the ResetEvents were set.  I see now that I need to nest the next tasks within the ContinueWhenAll, etc.  I'd be more comfortable if there were a WaitForAllTasksToComplete but I can't seem to find anything like that in Tasks.  Is there such a thing?  Thanks!
  • Monday, February 06, 2012 6:33 AM
    Moderator
     
     Answered

    Hi lwdaddio,

    If you could try to use Task.WaitAll() method

    http://msdn.microsoft.com/en-us/library/dd270695.aspx

     

    Best regards,


    Sheldon _Xiao[MSFT]
    MSDN Community Support | Feedback to us
    Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Marked As Answer by lwdaddio Tuesday, February 07, 2012 4:01 PM
    •