Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Updating UI from Task

Updating UI from Task

Scheduled Pinned Locked Moved C#
tutorialquestiondesignperformanceannouncement
4 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    GrooverFromHolland
    wrote on last edited by
    #1

    Hi All, In a tutorial I found a a new way (new for me)of updating a control from a thread. In the example code the new way(AsyncParallel) is in button1_Click and what I am familiar with is in button2_Click. They both do the job, but what is better, regarding performance and especially when more tasks are running that might update UI-thread? Here is the example:

    namespace Task_Compare
    {
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }
    
        private void button1\_Click(object sender, EventArgs e)
        {
    
            string data = "";
            Task Tf1 = Task.Factory.StartNew(() =>
                                  {
                                      data = GetData();
                                  });
    
            Task T2 = Tf1.ContinueWith((previousTask) =>
                                   {
                                      listBox1.Items.Insert(0, data);
                                   }, TaskScheduler.FromCurrentSynchronizationContext());
    
        }
    
        private void button2\_Click(object sender, EventArgs e)
        {
            string data = "";
            Task Tf2 = Task.Factory.StartNew(() =>
                                    {
                                        data = GetData();
                                    });
            Tf2.Wait();
    
            listBox1.Invoke(new EventHandler(delegate
            {
                listBox1.Items.Insert(0, data);
            }));
        }
    
        private string GetData()
        {
            string temp = "";
            {
                temp = " Do something long running ......";
            }
    
            return temp;
        }
    }
    

    }

    Groover,

    0200 A9 23 0202 8D 01 80 0205 00

    L 1 Reply Last reply
    0
    • G GrooverFromHolland

      Hi All, In a tutorial I found a a new way (new for me)of updating a control from a thread. In the example code the new way(AsyncParallel) is in button1_Click and what I am familiar with is in button2_Click. They both do the job, but what is better, regarding performance and especially when more tasks are running that might update UI-thread? Here is the example:

      namespace Task_Compare
      {
      public partial class Form1 : Form
      {

          public Form1()
          {
              InitializeComponent();
          }
      
          private void button1\_Click(object sender, EventArgs e)
          {
      
              string data = "";
              Task Tf1 = Task.Factory.StartNew(() =>
                                    {
                                        data = GetData();
                                    });
      
              Task T2 = Tf1.ContinueWith((previousTask) =>
                                     {
                                        listBox1.Items.Insert(0, data);
                                     }, TaskScheduler.FromCurrentSynchronizationContext());
      
          }
      
          private void button2\_Click(object sender, EventArgs e)
          {
              string data = "";
              Task Tf2 = Task.Factory.StartNew(() =>
                                      {
                                          data = GetData();
                                      });
              Tf2.Wait();
      
              listBox1.Invoke(new EventHandler(delegate
              {
                  listBox1.Items.Insert(0, data);
              }));
          }
      
          private string GetData()
          {
              string temp = "";
              {
                  temp = " Do something long running ......";
              }
      
              return temp;
          }
      }
      

      }

      Groover,

      0200 A9 23 0202 8D 01 80 0205 00

      L Offline
      L Offline
      Lost User
      wrote on last edited by
      #2

      GrooverFromHolland wrote:

      They both do the job, but what is better

      They do the same; which one is 'better' is nitpicking. If you want to pick the nits (which can be fun and educational), download ILspy and decompile the class. The Invoke-pattern is older than the Task-class, which was added in 4 (?). To some, the newer way is "more readable" as it does the same with less code (=fewer bugs). Others will be used to the old pattern. I prefer not to have a wait or an extra task, but to invoke the UI from the thread using the classical invoke-pattern from MSDN;

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
      using System.Windows.Forms;
      using System.Threading.Tasks;

      namespace ConsoleApplication2
      {
      class Program
      {
      static void Main()
      {
      System.Threading.Thread.CurrentThread.Name = "Main thread";
      using (var f = new SomeForm())
      f.ShowDialog();
      }
      }
      class SomeDataCollection : List { }
      class SomeForm: Form
      {
      ListBox _listBox1;
      Button _button1;
      public SomeForm()
      {
      _listBox1 = new ListBox() { Dock = DockStyle.Fill };
      _button1 = new Button() { Dock = DockStyle.Top };
      Controls.AddRange(new Control[] { _listBox1, _button1 });

              \_button1.Click += delegate
              {
                  Task Tf2 = Task.Factory.StartNew(() =>
                  {
                      SomeDataCollection \_data = getData();
                      showData(\_data);
                  });
              };
          }
          void showData(IList whatData)
          {
              if (InvokeRequired)
              {
                  Invoke(new Action(showData), new\[\] { whatData });
                  return;
              }
      
              \_listBox1.DataSource = whatData;
          }
          SomeDataCollection getData()
          {
              var result = new SomeDataCollection();
              for (int i = 0; i < 10; i++)
              {
                  result.Add(Guid.NewGuid());
                  System.Threading.Thread.Sleep(150);
              }
              return result;
          }
      }
      

      }

      I keep preferring the old style as it makes for very predictable code-constructs. I would however add that it's beneficial during debugging to name each thread during coding! Put a breakpoint on line 35, run, and when

      G 1 Reply Last reply
      0
      • L Lost User

        GrooverFromHolland wrote:

        They both do the job, but what is better

        They do the same; which one is 'better' is nitpicking. If you want to pick the nits (which can be fun and educational), download ILspy and decompile the class. The Invoke-pattern is older than the Task-class, which was added in 4 (?). To some, the newer way is "more readable" as it does the same with less code (=fewer bugs). Others will be used to the old pattern. I prefer not to have a wait or an extra task, but to invoke the UI from the thread using the classical invoke-pattern from MSDN;

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Text;
        using System.Windows.Forms;
        using System.Threading.Tasks;

        namespace ConsoleApplication2
        {
        class Program
        {
        static void Main()
        {
        System.Threading.Thread.CurrentThread.Name = "Main thread";
        using (var f = new SomeForm())
        f.ShowDialog();
        }
        }
        class SomeDataCollection : List { }
        class SomeForm: Form
        {
        ListBox _listBox1;
        Button _button1;
        public SomeForm()
        {
        _listBox1 = new ListBox() { Dock = DockStyle.Fill };
        _button1 = new Button() { Dock = DockStyle.Top };
        Controls.AddRange(new Control[] { _listBox1, _button1 });

                \_button1.Click += delegate
                {
                    Task Tf2 = Task.Factory.StartNew(() =>
                    {
                        SomeDataCollection \_data = getData();
                        showData(\_data);
                    });
                };
            }
            void showData(IList whatData)
            {
                if (InvokeRequired)
                {
                    Invoke(new Action(showData), new\[\] { whatData });
                    return;
                }
        
                \_listBox1.DataSource = whatData;
            }
            SomeDataCollection getData()
            {
                var result = new SomeDataCollection();
                for (int i = 0; i < 10; i++)
                {
                    result.Add(Guid.NewGuid());
                    System.Threading.Thread.Sleep(150);
                }
                return result;
            }
        }
        

        }

        I keep preferring the old style as it makes for very predictable code-constructs. I would however add that it's beneficial during debugging to name each thread during coding! Put a breakpoint on line 35, run, and when

        G Offline
        G Offline
        GrooverFromHolland
        wrote on last edited by
        #3

        Hi Eddy, Thank You for the good explanation. Regards, Groover

        0200 A9 23 0202 8D 01 80 0205 00

        L 1 Reply Last reply
        0
        • G GrooverFromHolland

          Hi Eddy, Thank You for the good explanation. Regards, Groover

          0200 A9 23 0202 8D 01 80 0205 00

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          You're welcome :)

          1 Reply Last reply
          0
          Reply
          • Reply as topic
          Log in to reply
          • Oldest to Newest
          • Newest to Oldest
          • Most Votes


          • Login

          • Don't have an account? Register

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • World
          • Users
          • Groups