C# 異步編程示例

從版本5.0開始塘秦,C#引入了async/await的異步編程模式定踱,大大簡化了異步編程的難度筷狼,使我們擺脫了回調(diào)函數(shù)瓶籽、事件等傳統(tǒng)的方式,可以使用類似同步編程的方式進行異步編程埂材,這里通過一個小例子說明這種編程方式以及需要注意的地方塑顺。

異步編程的主要目的是當執(zhí)行到耗時較多的過程時,先啟動這個過程俏险,然后繼續(xù)執(zhí)行后續(xù)代碼严拒,當需要這個過程的返回的值時,再進行等待竖独。這些耗時的過程可能是從網(wǎng)上下載文件裤唠,或者從數(shù)據(jù)庫讀入初始化數(shù)據(jù)等等。使用async/await方式編程時预鬓,需要使用async聲明需要異步執(zhí)行的過程巧骚,比如:

        async static Task<string> DoTask(int i)
        {
            Console.WriteLine("任務" + i+ "begin:" + Thread.CurrentThread.ManagedThreadId);
            await Task.Run(() => Console.WriteLine("任務" + i+ ":" + Thread.CurrentThread.ManagedThreadId));
            val = i.ToString();
            Console.WriteLine("任務" +i+ "end:" + Thread.CurrentThread.ManagedThreadId);
            return "任務"+i;

        }

async返回的類型是Task或者Task<>,如果沒有返回格二,可以是void。需要注意的是:async聲明的函數(shù)或者方法中竣蹦,必須有使用await語句執(zhí)行的異步代碼顶猜,否則這個函數(shù)或過程會被同步執(zhí)行。反過來痘括,使用await語句調(diào)用異步執(zhí)行代碼的函數(shù)长窄,也必須聲明為async。在同步函數(shù)中可以直接調(diào)用異步函數(shù)纲菌,使用Task.Result獲取結(jié)果值挠日,比如:

string res=DoTask(10).Result;

下面的代碼啟動若干異步任務:

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

namespace ZL.AsyncDemo
{
    class Program
    {
        static string val;
        static void Main(string[] args)
        {
            Run();
            Console.ReadLine();
        }
        
        async static void Run()
        {
            var tasks = new List<Task<string>>();
            for(var i = 0; i < 5; i++)
            {
                var task = DoTask(i);
                tasks.Add(task);
            }

            Console.WriteLine("任務Main:" + Thread.CurrentThread.ManagedThreadId);

            while (tasks.Any())
            {
                Task<string> finished = await Task<string>.WhenAny(tasks);
                Console.WriteLine(finished.Result);
                tasks.Remove(finished);
            }
            
            Console.WriteLine(val);
        }

        async static Task<string> DoTask(int i)
        {
            Console.WriteLine("任務" + i+ "begin:" + Thread.CurrentThread.ManagedThreadId);
            await Task.Run(() => Console.WriteLine("任務" + i+ ":" + Thread.CurrentThread.ManagedThreadId));
            val = i.ToString();
            Console.WriteLine("任務" +i+ "end:" + Thread.CurrentThread.ManagedThreadId);
            return "任務"+i;

        }
    }
}

從執(zhí)行結(jié)果看,這些任務不是在同一線程執(zhí)行的:


圖片.png

異步編程下需要注意的是訪問公用變量的問題翰舌,如果多個異步任務對同一公用變量進行修改的化嚣潜,結(jié)果可能不可預測,我們在這里定義了一個簡單的公用變量椅贱,在異步任務中對它進行賦值懂算,最后的結(jié)果是不可預測的只冻,上次執(zhí)行時結(jié)果是4,這次執(zhí)行就變成了2:


圖片.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末计技,一起剝皮案震驚了整個濱河市喜德,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌垮媒,老刑警劉巖舍悯,帶你破解...
    沈念sama閱讀 222,252評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異睡雇,居然都是意外死亡萌衬,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評論 3 399
  • 文/潘曉璐 我一進店門入桂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奄薇,“玉大人,你說我怎么就攤上這事抗愁∧俚伲” “怎么了?”我有些...
    開封第一講書人閱讀 168,814評論 0 361
  • 文/不壞的土叔 我叫張陵蜘腌,是天一觀的道長沫屡。 經(jīng)常有香客問我,道長撮珠,這世上最難降的妖魔是什么沮脖? 我笑而不...
    開封第一講書人閱讀 59,869評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮芯急,結(jié)果婚禮上勺届,老公的妹妹穿的比我還像新娘。我一直安慰自己娶耍,他們只是感情好免姿,可當我...
    茶點故事閱讀 68,888評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著榕酒,像睡著了一般胚膊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上想鹰,一...
    開封第一講書人閱讀 52,475評論 1 312
  • 那天紊婉,我揣著相機與錄音,去河邊找鬼辑舷。 笑死喻犁,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播株汉,決...
    沈念sama閱讀 41,010評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼筐乳,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乔妈?” 一聲冷哼從身側(cè)響起蝙云,我...
    開封第一講書人閱讀 39,924評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎路召,沒想到半個月后勃刨,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡股淡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,552評論 3 342
  • 正文 我和宋清朗相戀三年身隐,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片唯灵。...
    茶點故事閱讀 40,680評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡贾铝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出埠帕,到底是詐尸還是另有隱情垢揩,我是刑警寧澤,帶...
    沈念sama閱讀 36,362評論 5 351
  • 正文 年R本政府宣布敛瓷,位于F島的核電站叁巨,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏呐籽。R本人自食惡果不足惜锋勺,卻給世界環(huán)境...
    茶點故事閱讀 42,037評論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望狡蝶。 院中可真熱鬧庶橱,春花似錦、人聲如沸贪惹。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,519評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽馍乙。三九已至,卻和暖如春垫释,著一層夾襖步出監(jiān)牢的瞬間丝格,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,621評論 1 274
  • 我被黑心中介騙來泰國打工棵譬, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留显蝌,地道東北人。 一個月前我還...
    沈念sama閱讀 49,099評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像曼尊,于是被迫代替她去往敵國和親酬诀。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,691評論 2 361

推薦閱讀更多精彩內(nèi)容

  • 本文主要介紹了在 C# 中使用 Async 和 Await 關鍵字進行異步編程的心得,是入門級的學習筆記神郊。 題解:...
    BossOx閱讀 5,751評論 4 27
  • 原文連接:https://blog.csdn.net/sinat_17775997/article/details...
    小豆soybean閱讀 4,263評論 0 7
  • 什么是異步編程 什么是異步編程呢?舉個簡單的例子: 上面這段代碼中夕晓,Main方法中的代碼是按照自上而下的順序執(zhí)行的...
    雪飛鴻閱讀 4,418評論 0 12
  • 講師四期 翟沖【原創(chuàng)】分享第501天 2018.05.16 今天晚上是我們焦作焦點讀書會的日子宛乃,我們?nèi)缂s而至...
    春暖花開zc閱讀 57評論 0 0
  • 我撿起石頭在水里泛起了一陣波浪,山的那一頭傳來綿綿不絕的回響…… 年少時蒸辆,我們總會為了一顆糖而開心一整天征炼,也會為一...
    原版穆川閱讀 274評論 0 2