开发者

Task Parallel with .net framework 4

I am studying parallelism and would like t开发者_JAVA技巧o know which way do you recommend for me to access other thead elements, for example, imagima I'll fill a combobox with some names, query the database I would do in parallel but I could not do a combobox.add (result) from within the task, which way do you recommend me?

a simple example to understand my question:

 private void button1_Click (object sender, EventArgs e)
         {
             Task task = new Task (new Action (Count));
             task.Start ();
         }


         void Count ()
         {
             for (int i = 0; i <99; i + +)
             {
                 Thread.Sleep (1);
                 progressBar1.Value = i;
             }
         }

time to pass the value for the progressbar result in error


If you want to schedule a task that access UI controls, you need to pass the current synchronization context to the scheduler. If you do that the scheduler will make sure your task is executed on the correct thread. E.g.

var uiScheduler = TaskScheduler.FromCurrentSynchronizationContext();

Task.Factory.StartNew(() => {
    // code that access UI controls
}, uiScheduler);

For more info see http://msdn.microsoft.com/en-us/library/dd997402.aspx


You cannot access controls on another thread directly. You must invoke them first. Read this article: http://msdn.microsoft.com/en-us/library/ms171728.aspx

This is about what is would look like if you took the article and translated it for your own use: (NOT TESTED)

        delegate void SetProgressBarCallback();

        private void SetProgressBar()
        {
            // InvokeRequired required compares the thread ID of the
            // calling thread to the thread ID of the creating thread.
            // If these threads are different, it returns true.
            if (this.progressBar1.InvokeRequired)
            {   
                SetProgressBarCallback d = new SettProgressBarCallback(SetProgressBar);
                this.Invoke(d);         
            }
            else
            {
                for(int i=0; i<99; i++)
                {
                     Thread.Sleep(1);
                     progressBar1.Value = i;
                 }
            }
        }


Just a quick note... the UI in WinForms can only be updated from the UI thread. Perhaps you should consider using Control.Invoke to update your progressBar1.


Ryan's answer was correct but he put the sleep inside the invoke, that caused the program to hang. Here is a example that uses the same thing he did but it does not put the sleep in the invoke.

     private void button1_Click (object sender, EventArgs e)
     {
         Task task = new Task (new Action (Count));
         task.Start ();
     }


     void Count ()
     {
         for (int i = 0; i <99; i + +)
         {
             Thread.Sleep (1);
             if(progressBar1.InvokeRequired)
             {
                  int j = i; //This is required to capture the variable, if you do not do this
                             // the delegate may not have the correct value when you run it;
                  progressBar1.Invoke(new Action(() => progressBar1.Value = j));
             }
             else
             {
                 progressBar1.Value = i;
             }
         }
     }

You must do the int j = i to do variable capture, otherwise it could bring up the wrong value for i inside the loop.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜