異步編程學習

 

摘抄自文章:.NET中的異步編程html

異步編程中重要的技術點在於:編程

1)當異步線程在工做完成時,如何通知調用線程?多線程

2)當異步線程出現異常的時,該如何處理?異步

3)異步線程工做的進度,如何實時的通知調用線程?async

4)如何在調用線程中,取消正在工做的異步線程,並進行回滾操做?異步編程

 

完整的異步調用例子:函數

class Program
    {
        public delegate int DoWord(int count);
        static void Main(string[] args)
        {
            DoWord d = new DoWord(WorkPro);
            IAsyncResult r= d.BeginInvoke(100,CallBack ,d);//no.1
            for (int i = 0; i < 100; i++)
            {
                Thread.Sleep(10);//主線程須要作的事
            }
            Console.WriteLine("主線程done");
            Console.ReadKey();
        }
        public static int WorkPro(int count)
        {
            int sum = 0;
            //作一些耗時的工做
            for (int i = 0; i < count; i++)
            {
                sum += i;
                Thread.Sleep(10);
            }
            return sum;        
        }
 
        public static void CallBack(IAsyncResult r)
        {
            DoWord d = (DoWord)r.AsyncState;
            Console.WriteLine("異步調用完成,返回結果爲{0}", d.EndInvoke(r));
        }
    }

以上被博主稱之爲異步函數模型。post

 

Thread類this

class Program
    {
        static void Main(string[] args)
        {
            Thread t = new Thread(WorkPro);//no.1
            t.IsBackground = true;//no.2
            t.Start(1000);//no.3
        }
        public static void WorkPro(object  t)
        {
            //作一些耗時的工做   
            int count=(int)t;
            for (int i = 0; i < count; i++)
            {
                Thread.Sleep(2000);
            }
 
            Console.WriteLine("任務處理完成");
        }
    }
Thread類的使用雖然簡單,可是它仍是有必定的劣勢的,通常不推薦使用。
1)Thread類建立的是一個專用線程,創建一個專用線程是很是耗用系統的資源,建議是使用線程池中的線程。
2)Thread類不能很好的和調用線程進行交互,當任務完成時不能及時的通知,在調用線程也不能隨時的取消正在進行的任務。
另外在如下狀況下,就只能選擇使用 Thread類了。
1)執行任務的線程要以非普通的優先級去執行,由於線程池的線程都是以普通優先級運行的。
2)執行任務的線程要表現爲一個前臺線程,由於線程池的線程始終都是一個後臺線程。
3)異步執行的任務須要長時間的,那麼就能夠使用Thread類爲該任務創建一個專用線程。

 

Task類url

public partial class Form1 : Form
    {
        private readonly TaskScheduler contextTaskScheduler;//聲明一個任務調度器
        public Form1()
        {
            InitializeComponent();
            contextTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();//no.1得到一個上下文任務調度器
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            Task<int> t = new Task<int>((n) => Sum((int)n),100);
            t.Start();
            t.ContinueWith(task =>this.textBox1 .Text =task.Result.ToString(),contextTaskScheduler);//當任務執行完以後執行
            t.ContinueWith(task=>MessageBox .Show ("任務出現異常"),CancellationToken.None ,TaskContinuationOptions.OnlyOnFaulted,contextTaskScheduler );//當任務出現異常時才執行
        }
        int Sum(int count)
        {
            int sum = 0;
            for (int i = 0; i < count; i++)
            {
                Thread.Sleep(10);
                sum += i;
            }
            Console.WriteLine("任務處理完成");
            return sum;
        }
    }

這是一個比較完整的Task應用例子。詳情能夠閱讀摘抄的博客原文。

 

博客:Winform實現多線程異步更新UI(進度及狀態信息)

有個完整的使用多線程的例子。代碼比較複雜。

 

 ------------------------------

20190907更新

文章:C#異步的世界【上】

寫了早期C#中實現異步的方法。

 文章:C#異步的世界【下】

和上篇配合看

相關文章
相關標籤/搜索