C#多線程實現方法——Task/Task.Factary


Task

使用

Task以及Task.Factory都是在.Net 4引用的。Task跟Thread很類似,通過下面例子可以看到。

        static public void ThreadMain()
        {
            Thread t1 = new Thread(TaskWorker);
            t1.Start(3);
        }

        static public void TaskMain()
        {
            Task t1 = new Task(TaskWorker, 3, TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent);
            Console.WriteLine(t1.Status);
            t1.Start();
            t1.Wait(); // need to wait for finishing.
        }

        static public void TaskWorker(object state)
        {
            int nTime = (int)state;
            for (int i = 0; i < nTime; i++)
            {
                Thread.Sleep(100);
                Console.WriteLine(string.Format("current thread {0} sleep for {1} miniseconds .", Task.CurrentId, (i + 1) * 100));
            }
            return;
        }

我們看到TaskWorker都是用於Task以及Thread,都是只能接受一個參數(Action<object>),不過task可以支持工作函數具有返回值(Func<TRessult>()或者Func<object, TResult>)。但是弱的類型輸入跟thread一樣。Task提供返回值是為了后面說到的task結構層次有用。

下面是調用一個具有返回值的工作函數

        static public int TaskWorkerWithReturn(object state)
        {
            int nTime = (int)state;
            for (int i = 0; i < nTime; i++)
            {
                Thread.Sleep(100);
                Console.WriteLine(string.Format("current thread {0} sleep for {1} miniseconds .", Task.CurrentId, (i + 1) * 100));
            }
            nTime++;
            return nTime;
        }
 
        

主調函數為:

            Task<int> t2 = new Task<int>(TaskWorkerWithReturn, 3, TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent);
            t2.Start();
            t2.Wait();
            Console.WriteLine(t2.Result);
不管從工作函數是否有返回值,task都需要在其運行過程中至少有一個前台線程在跑,否則會直接退出,根本原因是所有task都是后台線程。task的工作函數的輸入參數類型職能是object。

同步

對於沒有返回值的工作函數需要通過內核對象來同步主調線程(例如task內置的事件,使用wait來阻塞等待);

對於有返回值的工作函數可以通過訪問其Result函數來實現阻塞等待。

        static public int TaskWorkerWithReturn(object state)
        {
            int nTime = (int)state;
            for (int i = 0; i < nTime; i++)
            {
                Thread.Sleep(100);
                Console.WriteLine(string.Format("current thread {0} sleep for {1} miniseconds .", Task.CurrentId, (i + 1) * 100));
            }
            nTime++;
            return nTime;
        }

主調函數:

            Task<int> t2 = new Task<int>(TaskWorkerWithReturn, 3, TaskCreationOptions.PreferFairness | TaskCreationOptions.LongRunning | TaskCreationOptions.AttachedToParent);
            t2.Start();
            Console.WriteLine("t2:" + t2.Result);

異步調用

作為新的一個特性在.net 4中引入,task能實現豐富的異步調用,使用成員函數ContinueWith來響應異步工作函數的完成,注意,不一定由之前完成異步函數的線程執行

        static public void TaskMain()
        {
            Task<int> t3 = new Task<int>(FirstTask, 1);
            t3.Start();
            Task<int> t4 = t3.ContinueWith<int>(RecusiveTask);
            Task<int> t5 = t4.ContinueWith<int>(RecusiveTask);
            Task<int> t6 = t5.ContinueWith<int>(RecusiveTask).ContinueWith<int>(RecusiveTask);
            //Console.WriteLine(string.Format("final result: {0}", t6.Result));
        }

        static public int FirstTask(object state)
        { 
            int data = (int)state;
            for (int i = 0; i < data; i++)
            {
                Thread.Sleep(100);
                Console.WriteLine(string.Format("current thread {0} slept for {1} milisecond.", Task.CurrentId, (i + 1) * 100));
            }
            data++;
            return data;
        }

        static public int RecusiveTask(Task<int> T)
        {
            int data = T.Result;
            for (int i = 0; i < data; i++)
            {
                Thread.Sleep(100);
                Console.WriteLine(string.Format("current thread {0} slept for {1} milisecond.", Task.CurrentId, (i + 1) * 100));
            }
            data++;
            return data;
        }
輸出結果為:

current thread 1 slept for 100 milisecond.
current thread 2 slept for 100 milisecond.
current thread 2 slept for 200 milisecond.
current thread 3 slept for 100 milisecond.
current thread 3 slept for 200 milisecond.
current thread 3 slept for 300 milisecond.
current thread 4 slept for 100 milisecond.
current thread 4 slept for 200 milisecond.
current thread 4 slept for 300 milisecond.
current thread 4 slept for 400 milisecond.
current thread 5 slept for 100 milisecond.
current thread 5 slept for 200 milisecond.
current thread 5 slept for 300 milisecond.
current thread 5 slept for 400 milisecond.
current thread 5 slept for 500 milisecond.
final result: 6
請按任意鍵繼續. . .














免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM