最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

.NET并發(fā)編程之函數(shù)閉包

 更新時(shí)間:2021年02月09日 21:39:38   作者:還俗和尚  
這篇文章主要介紹了.NET并發(fā)編程之函數(shù)閉包,有對(duì)于這方面不太懂的同學(xué)可以研究下

函數(shù)式編程

一個(gè)函數(shù)輸出當(dāng)做另一個(gè)函數(shù)輸入。有時(shí)候一個(gè)復(fù)雜問(wèn)題,我們拆分成很多個(gè)步驟函數(shù),這些函數(shù)組合起來(lái)調(diào)用解決一個(gè)復(fù)雜問(wèn)題。

在C#中不支持函數(shù)組合,但可以直接像這樣調(diào)用B(A(n)),這也是函數(shù)組合,但這不利于閱讀,人們習(xí)慣從左往右閱讀,而不是相反的方向。通過(guò)創(chuàng)建擴(kuò)展方法可以任何組合兩個(gè)函數(shù),像下面這樣

Func<A,C> Compose<A,B,C>(this Func<A.B> f ,Func<B,C> g)=>(n)=>g(f(n))

上述代碼為泛型委托Func<a,b>創(chuàng)建了一個(gè)擴(kuò)展Compose的擴(kuò)展方法,以泛型委托Func<b,c>為輸入?yún)?shù),返回組合后的函數(shù)Func<a,c>。創(chuàng)建一個(gè)高階函數(shù)Compose把不利于閱讀的隱藏起來(lái)。

在F#中就非常方便的使用函數(shù)組合。舉個(gè)例子,將一個(gè)列表中數(shù)字增加4再乘以3,構(gòu)建這兩個(gè)步驟的函數(shù)(當(dāng)然利用C#linq或F#map可以直接(x+4)*3,這里主要演示兩個(gè)功能函數(shù)如何組合起來(lái))。

letadd4x=x+4
letmulitply3x=x*3
letlist=[0..10]
letnewList=List.map(funx->mulitply3(add4(x)))list
letnewList2=list|>List.map(add4>>mulitply3

在F#中使用>>中綴運(yùn)算符來(lái)使函數(shù)組合可以從左到右閱讀,更加精煉、簡(jiǎn)潔。

閉包的應(yīng)用

閉包可以讓函數(shù)訪問(wèn)其所在的外部函數(shù)中的參數(shù)和變量,即使在其外部函數(shù)被返回之后。在js中經(jīng)常會(huì)出現(xiàn)閉包的場(chǎng)景,在C#和F#中,編譯器使用閉包來(lái)增加和擴(kuò)展變量的范圍。

C#在.NET2.0后引入閉包。在lambda和匿名方法中得到充分的使用。像下面的匿名函數(shù)引用變量a,訪問(wèn)和管理變量a的狀態(tài)。如果不用閉包,就需要額外創(chuàng)建一個(gè)類函數(shù)來(lái)調(diào)用。

strings="freevariable";
Func<string,string>lambda=value=>a+""+value;

以下載圖片更新窗體PictureBox控件為例:

void UpdateImage(string url)
{
  System.Windows.Forms.PictureBox picbox = this.pictureBox1;
  var client = new WebClient();
  client.DownloadDataCompleted += (o, e) =>
    {
      if (picbox != null)
      {
        using (var ms = new MemoryStream(e.Result))
        {
          picbox.Image = Image.FromStream(ms);
        }
      }
    };
  client.DownloadDataAsync(new Uri(url));
  //picbox = null;
}

因?yàn)槭钱惒较螺d,UPdateImage方法返回后,圖片還未下載完成,但picbox變量仍然可以使用。這就是變量捕獲。lambda表達(dá)式捕獲了局部變量image,因此它仍停留在作用域中。但捕獲的變量值是在運(yùn)行時(shí)確定的,而不是在捕獲時(shí),最后一句如果放開(kāi),將不能更新窗體。運(yùn)行時(shí)picbox為null了,在F#中不存在null的概念,所以也不會(huì)出現(xiàn)此類錯(cuò)誤。

多線程環(huán)境中的閉包使用。猜測(cè)下面的代碼運(yùn)行結(jié)果如何?

for (int i = 1; i < 10; i++)
{
  Task.Factory.StartNew(()=>Console.WriteLine("{0}-{1}",
    Thread.CurrentThread.ManagedThreadId,i));
}

不會(huì)按期望的那樣打印1-9,因?yàn)樗麄児蚕碜兞縤,調(diào)用時(shí)i的值可能已經(jīng)被循環(huán)修改了。印證上面說(shuō)的捕獲的變量值是在運(yùn)行時(shí)確定的。

這種情況就很難搞,給并行編程帶來(lái)了頭疼的問(wèn)題,變量可變,這不廢話嗎,變量不會(huì)變就不叫變量了。在C#中解決此類問(wèn)題的一個(gè)方法就是為每個(gè)任務(wù)創(chuàng)建創(chuàng)建和捕獲一個(gè)新的臨時(shí)變量,這樣它就能保留捕獲時(shí)的值。在F#中不存在這個(gè)問(wèn)題,它的For循環(huán)每次創(chuàng)建一個(gè)新的不可變值。

記憶化函數(shù)緩存

一些函數(shù)會(huì)頻繁的使用相同的參數(shù)去調(diào)用。我們可以將用相同的參數(shù)調(diào)用函數(shù)的結(jié)果存儲(chǔ)起來(lái),以便下次調(diào)用直接返回結(jié)果。例如對(duì)圖片每個(gè)像素做處理,一張圖片可能相同像素的會(huì)有很多,通過(guò)緩存可以直接返回上次計(jì)算結(jié)果。

//簡(jiǎn)單的函數(shù)緩存
public static Func<T, R> Memoize<T, R>(Func<T, R> func) where T : IComparable 
{
  Dictionary<T, R> cache = new Dictionary<T, R>();  
  return arg =>                    
  {
    if (cache.ContainsKey(arg))           
      return cache[arg];             
    return (cache[arg] = func(arg));        
  };
}

// 線程安全的函數(shù)緩存
public static Func<T, R> MemoizeThreadSafe<T, R>(Func<T, R> func) where T : IComparable
{
  ConcurrentDictionary<T, R> cache = new ConcurrentDictionary<T, R>();
  return arg => cache.GetOrAdd(arg, a => func(a));
}

// 利用延遲提高性能的函數(shù)緩存
public static Func<T, R> MemoizeLazyThreadSafe<T, R>(Func<T, R> func) where T : IComparable
{
  ConcurrentDictionary<T, Lazy<R>> cache = new ConcurrentDictionary<T, Lazy<R>>();
  return arg => cache.GetOrAdd(arg, a => new Lazy<R>(() => func(a))).Value;
}

上述示例代碼中有三個(gè)版本的函數(shù)記憶化。調(diào)用像下面這樣

public static string Greeting(string name)
{
  return $"Warm greetings {name}, the time is {DateTime.Now.ToString("hh:mm:ss")}";
}

public static void RunDemoMemoization()
{
  var greetingMemoize = Memoize<string, string>(Greeting);
  Console.WriteLine(greetingMemoize("Richard"));
  Console.WriteLine(greetingMemoize("Paul"));
  Console.WriteLine(greetingMemoize("Richard"));
}

線程安全字典ConcurrentDictionary可以保證只向集合里添加一個(gè)相同值,但函數(shù)求值可能會(huì)被執(zhí)行多次,所以利用.NET4之后的延遲對(duì)象加載技術(shù)。在真正需要使用對(duì)象時(shí)候才去實(shí)例化(通過(guò)訪問(wèn)延遲對(duì)象的Value屬性),而且是線程安全的。

到此這篇關(guān)于.NET并發(fā)編程之函數(shù)閉包的文章就介紹到這了,更多相關(guān).NET函數(shù)閉包內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • .Net中Task Parallel Library的進(jìn)階用法

    .Net中Task Parallel Library的進(jìn)階用法

    這篇文章介紹了.Net中Task Parallel Library的進(jìn)階用法,文中通過(guò)示例代碼介紹的非常詳細(xì)。對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-10-10
  • ASP.NET站點(diǎn)導(dǎo)航應(yīng)用詳解

    ASP.NET站點(diǎn)導(dǎo)航應(yīng)用詳解

    這篇文章主要內(nèi)容是ASP.NET站點(diǎn)導(dǎo)航,主要包括站點(diǎn)導(dǎo)航以及動(dòng)態(tài)修改內(nèi)存中的站點(diǎn)地圖,感興趣的小伙伴們可以參考一下
    2015-09-09
  • asp.net下常用的加密算法MD5、SHA-1應(yīng)用代碼

    asp.net下常用的加密算法MD5、SHA-1應(yīng)用代碼

    在進(jìn)行軟件開(kāi)發(fā)的過(guò)程中,為了提高系統(tǒng)的安全性能,經(jīng)常需要進(jìn)行敏感信息的加密處理。特別是在密碼儲(chǔ)存、文件傳輸、頁(yè)面?zhèn)髦档确矫妫瑢?duì)信息進(jìn)行加密顯得十分必要。下面介紹我們常用的兩種加密算法MD5、SHA1。
    2008-09-09
  • VS2013設(shè)置護(hù)眼背景顏色

    VS2013設(shè)置護(hù)眼背景顏色

    我們做開(kāi)發(fā)的一做基本都是一天,對(duì)著屏幕眼鏡肯定會(huì)累,下面教大家一個(gè)VS2013設(shè)置護(hù)眼背景色的方法。
    2016-04-04
  • Asp.Net 通用數(shù)據(jù)操作類 (附通用數(shù)據(jù)基類)

    Asp.Net 通用數(shù)據(jù)操作類 (附通用數(shù)據(jù)基類)

    以前經(jīng)常用php的數(shù)據(jù)操作類,這次的asp.net數(shù)據(jù)操作類,是個(gè)方法
    2008-07-07
  • .Net?Api?中使用Elasticsearch存儲(chǔ)文檔的方法

    .Net?Api?中使用Elasticsearch存儲(chǔ)文檔的方法

    Elasticsearch 是一個(gè)分布式、高擴(kuò)展、高實(shí)時(shí)的搜索與數(shù)據(jù)分析引擎,在C# 的環(huán)境中,有一個(gè)Es的官方拓展包Nest,可以讓我們方便快捷的使用上Es數(shù)據(jù)庫(kù),本文重點(diǎn)給大家介紹.Net?Api?中使用Elasticsearch存儲(chǔ)文檔的方法,感興趣的朋友一起看看吧
    2022-01-01
  • 如何在ASP.NET Core中給上傳圖片功能添加水印實(shí)例代碼

    如何在ASP.NET Core中給上傳圖片功能添加水印實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于如何在ASP.NET Core中給上傳圖片功能添加水印的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • 詳解.NET Core 3.0中的新變化

    詳解.NET Core 3.0中的新變化

    這篇文章主要介紹了詳解.NET Core 3.0中的新變化,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-03-03
  • asp.net驗(yàn)證碼的簡(jiǎn)單制作

    asp.net驗(yàn)證碼的簡(jiǎn)單制作

    當(dāng)用戶進(jìn)行注冊(cè)、登陸的時(shí)候都會(huì)遇到輸入驗(yàn)證碼的情況,那驗(yàn)證碼到底是怎么制作的,下面就為大家講解如何使用ASP.NET制作簡(jiǎn)單的驗(yàn)證碼,感興趣的朋友可以參考一下
    2015-09-09
  • 淺談ASP.NET的include的使用方法

    淺談ASP.NET的include的使用方法

    include:這是今天的主題,我想沒(méi)有什么比一個(gè)UI更說(shuō)明問(wèn)題了,那么這是一個(gè)什么頁(yè)面呢?詳見(jiàn)下面。
    2013-03-03

最新評(píng)論

玉屏| 奉节县| 万州区| 环江| 大名县| 菏泽市| 广东省| 本溪| 贺兰县| 九龙城区| 桃源县| 建阳市| 宁国市| 莆田市| 阿克| 凌云县| 葫芦岛市| 贵溪市| 肥东县| 定襄县| 海南省| 东乌珠穆沁旗| 开化县| 天气| 横峰县| 吐鲁番市| 民勤县| 新化县| 武乡县| 桂平市| 海淀区| 东台市| 马龙县| 马公市| 通榆县| 凤阳县| 宜城市| 定安县| 普宁市| 抚宁县| 阿克|