ios 异步ui_UI异步编程

ios 异步ui

Mulithreading is a wonderful concept but it is one of the most complex way to achieve a task. Microsoft had provided probably the most efficient way to handle this problem by using async calls and thread pool. This provides an easy way to handle more than one task in an efficient way. But the biggest problem is thread creation and disposal of thread in this programming scenario. A common problem we are facing with UI programming is we are executing a task which takes a long time.

Mulithreading是一个很棒的概念,但是它是完成任务的最复杂的方法之一。 Microsoft通过使用异步调用和线程池提供了可能最有效的方法来解决此问题。 这提供了一种以有效方式处理多个任务的简便方法。 但是最大的问题是在此编程方案中线程的创建和线程的处置。 UI编程面临的一个常见问题是我们正在执行需要很长时间的任务。

And if we are trying to do the same in Main Thread of application it freezes the UI until the completion of job. For example in the given program we are trying to run infinite loop and trying the display the count on textbox

而且,如果我们尝试在应用程序的主线程中执行相同的操作,则它将冻结UI直到作业完成。 例如,在给定程序中,我们尝试运行无限循环并尝试在文本框上显示计数

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        private TextBox textBox1;
        private Button btnStart;
    
        public Form1()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            this.btnStart = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // btnStart
            // 
            this.btnStart.Location = new System.Drawing.Point(134, 27);
            this.btnStart.Name = "btnStart";
            this.btnStart.Size = new System.Drawing.Size(75, 23);
            this.btnStart.TabIndex = 0;
            this.btnStart.Text = "Start";
            this.btnStart.UseVisualStyleBackColor = true;
            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(12, 29);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 20);
            this.textBox1.TabIndex = 1;
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.btnStart);
            this.Name = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        /// <summary>
        /// Updates the textbox
        /// </summary>
        /// <param name="i">Value to be updated</param>
        private void UpdateTextBox(int i)
        {
            textBox1.Text = i.ToString();
        }

        /// <summary>
        /// Start counting
        /// </summary>
        /// <param name="i">Intial value</param>
        private void Count(int i)
        {
            while (true)
            {
                i++;
                UpdateTextBox(i);
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            Count(0);
        }

    }
}

One of the better ways to solve this is pushing the time consuming task to a different thread and update the UI with callback method.

解决此问题的更好方法之一是将耗时的任务推送到其他线程,并使用回调方法更新UI。

One of best way to achieve this is by using BackgroundWorker class

实现此目的的最佳方法之一是使用BackgroundWorker

using System;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        private TextBox textBox1;
        private System.ComponentModel.BackgroundWorker backgroundWorker1;
        private Button btnStart;
    
        public Form1()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            this.btnStart = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.backgroundWorker1 = new System.ComponentModel.BackgroundWorker();
            this.SuspendLayout();
            // 
            // btnStart
            // 
            this.btnStart.Location = new System.Drawing.Point(134, 27);
            this.btnStart.Name = "btnStart";
            this.btnStart.Size = new System.Drawing.Size(75, 23);
            this.btnStart.TabIndex = 0;
            this.btnStart.Text = "Start";
            this.btnStart.UseVisualStyleBackColor = true;
            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(12, 29);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 20);
            this.textBox1.TabIndex = 1;
            // 
            // backgroundWorker1
            // 
            this.backgroundWorker1.DoWork += new System.ComponentModel.DoWorkEventHandler(this.backgroundWorker1_DoWork);
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.btnStart);
            this.Name = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        /// <summary>
        /// Updates the textbox
        /// </summary>
        /// <param name="i">Value to be updated</param>
        private void UpdateTextBox(int i)
        {
            textBox1.Text = i.ToString();
        }

        /// <summary>
        /// Start counting
        /// </summary>
        /// <param name="i">Intial value</param>
        private void Count(int i)
        {
            while (true)
            {
                i++;
                this.Invoke(new Action<int>((x) => textBox1.Text = x.ToString()), i);
                
            }
        }

        private void btnStart_Click(object sender, EventArgs e)
        {
            backgroundWorker1.RunWorkerAsync();
        }

        private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            Count(0);
        }

    }
}
using System;
using System.Windows.Forms;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        private TextBox textBox1;
        private Button btnStart;
    
        public Form1()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            this.btnStart = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // btnStart
            // 
            this.btnStart.Location = new System.Drawing.Point(134, 27);
            this.btnStart.Name = "btnStart";
            this.btnStart.Size = new System.Drawing.Size(75, 23);
            this.btnStart.TabIndex = 0;
            this.btnStart.Text = "Start";
            this.btnStart.UseVisualStyleBackColor = true;
            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(12, 29);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 20);
            this.textBox1.TabIndex = 1;
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.btnStart);
            this.Name = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        private void UpdateTextBox(int i)
        {
            textBox1.Text = i.ToString();
        }

        private void Count(int i)
        {
            while (true)
            {
                i++;
                this.Invoke(new Action<int>((x) => textBox1.Text = x.ToString()), i);
            }
        }


        private void btnStart_Click(object sender, EventArgs e)
        {
            int i = 0;
            new Action<int>(Count).BeginInvoke(i, null, null);
        }
    }
}

And similar thing can be achieved with Task Class from .net 4.0 onwards.

从.net 4.0开始,使用Task Class也可以实现类似的目的。

using System;
using System.Timers;
using System.Threading;
using System.Windows.Forms;
using System.Threading.Tasks;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        private TextBox textBox1;
        private Button btnStart;
    
        public Form1()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            this.btnStart = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // btnStart
            // 
            this.btnStart.Location = new System.Drawing.Point(134, 27);
            this.btnStart.Name = "btnStart";
            this.btnStart.Size = new System.Drawing.Size(75, 23);
            this.btnStart.TabIndex = 0;
            this.btnStart.Text = "Start";
            this.btnStart.UseVisualStyleBackColor = true;
            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(12, 29);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 20);
            this.textBox1.TabIndex = 1;
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.btnStart);
            this.Name = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        private void UpdateTextBox(int i)
        {
            textBox1.Text = i.ToString();
        }

        private void Count()
        {
            int i=0;
            while (true)
            {
                
                this.Invoke(new Action<int>((x) => textBox1.Text = x.ToString()), i++);
            }
        }


        private void btnStart_Click(object sender, EventArgs e)
        {
            Task.Factory.StartNew(new Action(Count));
        }
    }
}

and making it more compact:

并使其更紧凑:

using System;
using System.Timers;
using System.Threading;
using System.Windows.Forms;
using System.Threading.Tasks;

namespace WindowsFormsApplication2
{
    public partial class Form1 : Form
    {
        private TextBox textBox1;
        private Button btnStart;
    
        public Form1()
        {
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            this.btnStart = new System.Windows.Forms.Button();
            this.textBox1 = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // btnStart
            // 
            this.btnStart.Location = new System.Drawing.Point(134, 27);
            this.btnStart.Name = "btnStart";
            this.btnStart.Size = new System.Drawing.Size(75, 23);
            this.btnStart.TabIndex = 0;
            this.btnStart.Text = "Start";
            this.btnStart.UseVisualStyleBackColor = true;
            this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
            // 
            // textBox1
            // 
            this.textBox1.Location = new System.Drawing.Point(12, 29);
            this.textBox1.Name = "textBox1";
            this.textBox1.Size = new System.Drawing.Size(100, 20);
            this.textBox1.TabIndex = 1;
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(292, 273);
            this.Controls.Add(this.textBox1);
            this.Controls.Add(this.btnStart);
            this.Name = "Form1";
            this.ResumeLayout(false);
            this.PerformLayout();

        }


        private void btnStart_Click(object sender, EventArgs e)
        {
            Task.Factory.StartNew((Action)delegate()
                                  {
                                      int i = 0;
                                      while (true)
                                      {
                                          this.Invoke(new Action<int>((x) => textBox1.Text = x.ToString()), i++);
                                      }
                                  });
        }
    }
}

Please note that in all these method Thread is taken from ThreadPool

请注意,在所有这些方法中,线程均来自ThreadPool

翻译自: https://www.experts-exchange.com/articles/13575/Asynchronous-programming-with-UI.html

ios 异步ui

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值