Uzamčený Foreach wait for task to complete...

  • 12. dubna 2012 11:27
     
      Obsahuje kód

    I have a such situtation:

    foreach (var item in listBoxFileNames.SelectedItems)
                    {
    		    MessageBox.Show("I am not waiting");
                        CancellationTokenSource tokenSourcve = new CancellationTokenSource();
                        CancellationToken token = tokenSourcve.Token;
    
                        Task task1 = new Task(() =>
                            {
                                ProcessDatas(); // method
                            }
                            , token);
    
                        task1.Start();
                    }

    I want to make foreach to wait task's completion. BUt it is not waiting. It showing me MessageBox immediately after each messagBox.


    Ferhad Jabiyev

Všechny reakce

  • 12. dubna 2012 11:55
     
     

    Hi,

    Please just check the documentation at http://msdn.microsoft.com/en-us/library/dd537609.aspx and scroll down to "Waiting on tasks". As most often, some details about your overall goal could help to raise better suggestions if this is not enough...


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

  • 12. dubna 2012 11:56
     
     
    When you want to wait for each task, then why do you want to use tasks at all?
  • 12. dubna 2012 11:58
     
     
    Because the process inside it making window "not responding" if not use Tasks.

    Ferhad Jabiyev

  • 12. dubna 2012 12:07
     
     

    Another option could be to use a BackgroundWorker : http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

  • 12. dubna 2012 12:12
     
     
    I am using WPF.

    Ferhad Jabiyev

  • 12. dubna 2012 12:28
     
     

    Hi,

    try using WaitCallBack and thread pool. you can call WaitCallBack.WaitOne to wait for the task completion. Once again, if you suspend the foreach waiting for task to complete then the UI will be unavailable in this case there're no differents between calling ProcessData directly and waiting for it to complete.


    Bilhan silva

  • 12. dubna 2012 12:30
     
     
    But hte window isnt responding me during the process.

    Ferhad Jabiyev

  • 12. dubna 2012 12:37
     
      Obsahuje kód

    If you want to run this code without locking the ui, then you need to move the whole code block into a different thread. Try this:

    private void Test(object state)
    {
    foreach (var item in listBoxFileNames.SelectedItems)
                    {
    		    MessageBox.Show("I am not waiting");
                    
                                ProcessDatas(); // method
                    }
    }
    
    //Use this call instead of calling test directly
     ThreadPool.QueueUserWorkItem(new WaitCallback(Test));


    Bilhan silva

  • 12. dubna 2012 12:42
     
     

    But it throwing error:

    The calling thread cannot access this object because a different thread owns it.


    Ferhad Jabiyev

  • 12. dubna 2012 12:46
     
     
    This means that in your ProcessData method you're trying to access a control or something from the background thread. can you post the ProcessData method here?

    Bilhan silva

  • 12. dubna 2012 12:47
     
     
    Not i used it even without any method in foreach. again same error.

    Ferhad Jabiyev

  • 12. dubna 2012 13:05
     
     Odpovědět Obsahuje kód

    My fault, i rechecked the code i wrote, the error is in the foreach loop it self where you're accessing the listBoxFileNames from the background thread. here is the corrected code:

    List<object> listboxItems = new List<object>();
    private void Test(object state)
    {
    foreach (var item in listboxItems )
                    {
    		    MessageBox.Show("I am not waiting");
                    
                                ProcessDatas(); // method
                    }
    }
    
    //Use this call instead of calling test directly 
                foreach (object o in listBoxFileNames.SelectedItems)
                    listboxItems.Add(o);
    
     ThreadPool.QueueUserWorkItem(new WaitCallback(Test));


    Bilhan silva


  • 12. dubna 2012 15:56
     
     

    Ah. Then you may want to use a BackgroundWorker ;-). In this particular case, this is part of System.ComponentModel rather than just Windows Forms so it is not specifically tied to Windows Forms. See http://msdn.microsoft.com/en-us/magazine/cc163328.aspx#S4


    Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".