精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

C# Actor的尷尬與F#美麗外表下的遺憾

開發 開發工具
本文從Erlang的Tag Message開始,講述C# Actor中存在的一些問題。最后作者又提到了F#的模式匹配,以及F#中存在的問題。

上一篇文章中,我們簡單解讀了Erlang在執行消息時候的方式。而現在,我們就一起來看看,C# Actor究竟出現了什么樣的尷尬。此外,我還打算用F#進行補充說明,最終我們會發現,雖然F#看上去很美,但是在實際使用過程中依舊有些遺憾。

Erlang中的Tag Message

老趙在上一篇文章里提到,Erlang中有一個“約定俗成”,使用“原子(atom)”來表示這條消息“做什么”,并使用“綁定(binding)”來獲取做事情所需要的“參數”。Erlang大拿,《Programming Erlang》一書的主要譯者jackyz同學看了老趙的文章后指出,這一點在Erlang編程規范中有著明確的說法,是為“Tag Message”:

5.7 Tag messages

All messages should be tagged. This makes the order in the receive statement less important and the implementation of new messages easier.

Don’t program like this:

  1. loop(State) ->  
  2.   receive  
  3.     ...  
  4.     {Mod, Funcs, Args} -> % Don't do this 
  5.       apply(Mod, Funcs, Args},  
  6.       loop(State);  
  7.     ...  
  8.   end. 

If messages are synchronous, the return message should be tagged with a new atom, describing the returned message. Example: if the incoming message is tagged get_status_info, the returned message could be tagged status_info. One reason for choosing different tags is to make debugging easier.

This is a good solution:

  1. loop(State) ->  
  2.   receive  
  3.     ...  
  4.     {execute, Mod, Funcs, Args} -> % Use a tagged message.  
  5.       apply(Mod, Funcs, Args},  
  6.       loop(State);  
  7.     {get_status_info, From, Option} ->  
  8.       From ! {status_info, get_status_info(Option, State)},  
  9.       loop(State);      
  10.     ...  
  11.   end.  

第一段代碼使用的模式為擁有三個“綁定”的“元組”。由于Erlang的弱類型特性,任何擁有三個元素的元組都會被匹配到,這不是一個優秀的實踐。在第二個示例中,每個模式使用一個“原子”來進行約束,這樣可以獲取到相對具體的消息。為什么說“相對”?還是因為Erlang的弱類型特性,Erlang無法對From和Option提出更多的描述。同樣它也無法得知execute或get_status_info這兩個tag的來源——當然,在許多時候,它也不需要關心是誰發送給它的。

在C#中使用Tag Message

在C#中模擬Erlang里的Tag Message很簡單,其實就是把每條消息封裝為Tag和參數列表的形式。同樣的,我們使用的都是弱類型的數據——也就是object類型。如下:

  1. public class Message  
  2. {  
  3.     public object Tag { getprivate set; }  
  4.  
  5.     public ReadOnlyCollection﹤object> Arguments { getprivate set; }  
  6.  
  7.     public Message(object tag, params object[] arguments)  
  8.     {  
  9.         this.Tag = tag;  
  10.         this.Arguments = new ReadOnlyCollection﹤object>(arguments);  
  11.     }  
  12. }  

我們可以使用這種方式來實現一個乒乓測試。既然是Tag Message,那么定義一些Tag便是首要任務。Tag表示“做什么”,即消息的“功能”。在乒乓測試中,有兩種消息,共三個“含義”。Erlang使用原子作為tag,在.NET中我們自然可以使用枚舉:

  1. public enum PingMsg  
  2. {   
  3.     Finished,  
  4.     Ping  
  5. }  
  6.  
  7. public enum PongMsg  
  8. {   
  9.     Pong  
  10. }  

在這里,我們使用簡單的ActorLite進行演示(請參考ActorLite的使用方式)。因此,Ping和Pong均繼承于Actor﹤Message>類,并實現其Receive方法。

對于Ping對象來說,它會維護一個計數器。每當收到PongMsg.Pong消息后,會將計數器減1。如果計數器為0,則回復一條PingMsg.Finished消息,否則就回復一個PingMsg.Ping:

  1. public class Ping : Actor﹤Message>  
  2. {  
  3.     private int m_count;  
  4.  
  5.     public Ping(int count)  
  6.     {  
  7.         this.m_count = count;  
  8.     }  
  9.  
  10.     public void Start(Actor﹤Message> pong)  
  11.     {  
  12.         pong.Post(new Message(PingMsg.Ping, this));  
  13.     }  
  14.  
  15.     protected override void Receive(Message message)  
  16.     {  
  17.         if (message.Tag.Equals(PongMsg.Pong))  
  18.         {  
  19.             Console.WriteLine("Ping received pong");  
  20.  
  21.             var pong = message.Arguments[0] as Actor﹤Message>;  
  22.             if (--this.m_count > 0)  
  23.             {  
  24.                 pong.Post(new Message(PingMsg.Ping, this));  
  25.             }  
  26.             else 
  27.             {  
  28.                 pong.Post(new Message(PingMsg.Finished));  
  29.                 this.Exit();  
  30.             }  
  31.         }  
  32.     }  
  33. }  

對于Pong對象來說,如果接受到PingMsg.Ping消息,則回復一個PongMsg.Pong。如果接受的消息為PingMsg.Finished,便立即退出:

  1. public class Pong : Actor﹤Message>  
  2. {  
  3.     protected override void Receive(Message message)  
  4.     {  
  5.         if (message.Tag.Equals(PingMsg.Ping))  
  6.         {  
  7.             Console.WriteLine("Pong received ping");  
  8.  
  9.             var ping = message.Arguments[0] as Actor﹤Message>;  
  10.             ping.Post(new Message(PongMsg.Pong, this));  
  11.         }  
  12.         else if (message.Tag.Equals(PingMsg.Finished))  
  13.         {  
  14.             Console.WriteLine("Finished");  
  15.             this.Exit();  
  16.         }  
  17.     }  
  18. }  

啟動乒乓測試:

new Ping(5).Start(new Pong());結果如下:

Pong received ping
Ping received pong
Pong received ping
Ping received pong
Pong received ping
Ping received pong
Pong received ping
Ping received pong
Pong received ping
Ping received pong
Finished

從上述代碼中可以看出,由于沒有Erlang的模式匹配,我們必須使用if…else…的方式來判斷消息的Tag,接下來還必須使用麻煩而危險的cast操作來獲取參數。更令人尷尬的是,與Erlang相比,在C#中使用Tag Message沒有獲得任何好處。同樣是弱類型,同樣得不到靜態檢查。那么好處在哪里?至少我的確看不出來。

C# Actor,強類型與弱類型的考慮

有朋友可能會說,C#既然是一門強類型的語言,為什么要學Erlang的Tag Message?為什么不把Ping定義為Actor﹤PingMessage>,同時把Pong定義為Actor﹤PingMessage>呢?

呃……我承認,在這里使用Tag Message的確有種“畫虎不成反類犬”的味道。不過,事情也不是您想象的那么簡單。因為在實際情況中,一個Actor可能與各種外部服務打交道,它會接受到各式各樣的消息。例如,它先向Service Locator發送一個請求,用于查詢數據服務的位置,這樣它會接受到一個ServiceLocatorResponse消息。然后,它會向數據服務發送一個請求,再接受到一個DataAccessResponse消息。也就是說,很可能我們必須把每個Actor都定義為Actor﹤object>,然后對消息進行類型判斷,轉換,再加以處理。

誠然,這種方法相對于Tag Message擁有了一定的強類型優勢(如靜態檢查)。但是如果您選擇這么做,就必須為各種消息定義不同的類型,在這方面會帶來額外的開發成本。要知道,消息的數量并不等于Actor類型的數量,即使是如Ping這樣簡單的Actor,都會發送兩種不同的消息(Ping和Finished),而且每種消息擁有各自的參數。一般來說,某個Actor會接受2-3種消息都是比較正常的狀況。在面對消息類型的汪洋時,您可能就會懷念Tag Message這種做法了。到時候您可能就會發牢騷說:

“弱類型就弱類型吧,Erlang不也用的好好的么……”

F#中的模式匹配

提到模式匹配,熟悉F#的同學們可能會歡喜不已。模式匹配是F#中的重要特性,它將F#中靜態類型系統的靈活性體現地淋漓盡致。而且——它還很能節省代碼(這點在老趙以前的文章中也有所提及)。那么我們再來看一次F#在乒乓測試中的表現。

首先還是定義PingMsg和PongMsg:

  1. type PingMsg =   
  2.     | Ping of PongMsg Actor  
  3.     | Finished  
  4. and PongMsg =   
  5.     | Pong of PingMsg Actor 

這里體現了F#類型系統中的Discriminated Unions。簡單地說,它的作用是把一種類型定義為多種表現形式,這個特性在Haskell等編程語言中非常常見。Discriminated Unions非常適合模式匹配,現在的ping對象和pong對象便可定義如下(在這里還是使用了ActorLite,而不是F#標準庫中的MailboxProcessor來實現Actor模型):

  1. let (﹤﹤) (a:_ Actor) msg = a.Post msg  
  2.  
  3. let ping =  
  4.     let count = ref 5  
  5.     { new PongMsg Actor() with  
  6.         override self.Receive(message) =  
  7.             match message with  
  8.             | Pong(pong) ->  
  9.                 printfn "Ping received pong" 
  10.                 count := !count - 1  
  11.                 if (!count > 0) then  
  12.                     pong ﹤﹤ Ping(self)  
  13.                 else 
  14.                     pong ﹤﹤ Finished  
  15.                     self.Exit() }  
  16.  
  17. let pong =   
  18.     { new PingMsg Actor() with  
  19.         override self.Receive(message) =  
  20.             match message with  
  21.             | Ping(ping) ->  
  22.                 printfn "Pong received ping" 
  23.                 ping ﹤﹤ Pong(self)  
  24.             | Finished ->  
  25.                 printf "Fininshed" 
  26.                 self.Exit() }  

例如在pong對象的實現中,我們使用模式匹配,減少了不必要的類型轉換和賦值,讓代碼變得簡潔易讀。還有一點值得順帶一提,我們在F#中可以靈活的定義一個操作符的作用,在這里我們便把“﹤﹤”定義為“發送”操作,避免Post方法的顯式調用。這種做法往往可以簡化代碼,從語義上增強了代碼的可讀性。例如,我們可以這樣啟動乒乓測試:

ping ﹤﹤ Pong(pong)至于結果則與C#的例子一模一樣,就不再重復了。

F#中的弱類型消息

可是,F#的世界就真的如此美好嗎?試想,我們該如何實現一個需要接受多種不同消息的Actor對象呢?我們只能這樣做:

  1. let another =   
  2.     { new obj Actor() with  
  3.         override self.Receive(message) =  
  4.             match message with  
  5.               
  6.             | :? PingMsg as pingMsg ->  
  7.                 // sub matching  
  8.                 match pingMsg with  
  9.                 | Ping(pong) -> null |> ignore  
  10.                 | Finished -> null |> ignore  
  11.                   
  12.             | :? PongMsg as pongMsg ->  
  13.                 // sub matching  
  14.                 match pongMsg with  
  15.                 | Pong(ping) -> null |> ignore  
  16.                   
  17.             | :? (string * intas m ->  
  18.                 // sub binding  
  19.                 let (s, i) = m  
  20.                 null |> ignore  
  21.                   
  22.             | _ -> failwith "Unrecognized message" } 

由于我們必須使用object作為Actor接受到的消息類型,因此我們在對它作模式匹配時,只能進行參數判斷。如果您要更進一步地“挖掘”其中的數據,則很可能需要進行再一次的模式匹配(如PingMsg或PongMsg)或賦值(如string * int元組)。一旦出現這種情況,在我看來也變得不是那么理想了,我們既沒有節省代碼,也沒有讓代碼變得更為易讀。與C#相比,唯一的優勢可能就是F#中相對靈活的類型系統吧。

C# Actor不好用,F#也不行……那么我們又該怎么辦?

【編輯推薦】

  1. 看Erlang中Actor模型的執行方式和優劣
  2. Erlang面向分布與并發的編程語言
  3. Erlang十分鐘快速入門
  4. 因并發而生 因云計算而熱:Erlang專家訪談實錄
  5. 淺析Erlang分布的核心技術
責任編輯:yangsai 來源: 老趙點滴
相關推薦

2009-08-20 18:13:03

F#和C#

2010-04-07 16:51:59

F#

2010-01-07 10:04:18

F#函數式編程

2010-01-26 08:25:06

F#語法F#教程

2012-03-12 12:34:02

JavaF#

2009-05-01 11:17:41

ADNF5思科

2009-09-10 14:18:59

Functional F#

2022-11-10 08:26:54

.NET 7C# 11

2010-03-26 19:22:08

F#代理

2009-11-16 09:05:46

CodeTimer

2010-05-13 09:21:44

F#Visual Stud

2010-04-06 15:20:56

ASP.NET MVC

2010-01-15 08:33:13

F#F#類型推斷F#教程

2009-08-05 16:04:27

C# Actor模型

2010-03-26 19:03:19

F#異步并行模式

2009-08-13 17:39:48

F#數據類型Discriminat

2011-06-09 09:52:41

F#

2009-11-09 17:51:51

F#函數式編程

2010-03-26 18:31:59

F#異步并行模式

2009-08-19 09:42:34

F#并行排序算法
點贊
收藏

51CTO技術棧公眾號

国产精品国产三级在线观看| 大片免费播放在线视频| 欧美日本一区二区视频在线观看| 日韩视频免费观看高清完整版| 777久久精品一区二区三区无码 | 四虎永久免费在线观看| 欧美aaa大片视频一二区| 亚洲日本成人在线观看| 国产精品区二区三区日本| 99久久久久久久久| 你懂的一区二区| 亚洲男子天堂网| 国产欧美精品一二三| 亚洲福利影院| 一区二区三区视频在线看| 鲁丝一区鲁丝二区鲁丝三区| 国产毛片久久久久| 国产精品一二| 欧美理论片在线观看| 国产成人精品无码免费看夜聊软件| 亚洲成人1区| 欧美日韩国产一中文字不卡| 中文字幕制服丝袜在线| 欧美成人片在线| 成人视屏免费看| 国产精品视频一区二区高潮| 国产精品111| 亚洲xxx拳头交| 国产一区二区三区在线视频 | 久久97精品久久久久久久不卡| 国产男男chinese网站| 日韩精品免费视频一区二区三区| 欧美羞羞免费网站| 国产极品在线视频| 中文在线免费| 中文字幕一区二区三中文字幕| 美女视频久久| 天天av天天翘| 成人激情av网| 国产精品精品软件视频| jizz中国少妇| 国产精品一区二区三区四区 | 日韩精品视频久久| 国产在线xxx| 亚洲精品美腿丝袜| 法国空姐在线观看免费| 午夜在线免费观看视频| 久久久久9999亚洲精品| 精品人伦一区二区三区| 狠狠躁日日躁夜夜躁av| 成人性生交大片免费| 超碰97国产在线| 肥臀熟女一区二区三区| 高清在线观看日韩| 国产精品xxx在线观看www| 亚洲国产精品视频在线| 成人免费视频视频在线观看免费| 99在线观看视频| 免费a级片在线观看| 国产成人99久久亚洲综合精品| 亚洲aa中文字幕| 国产sm主人调教女m视频| 国产v日产∨综合v精品视频| 99久久伊人精品影院| 性生活免费网站| 粉嫩aⅴ一区二区三区四区五区| 国产成人精品福利一区二区三区| 亚洲国产福利视频| www国产精品av| 日本精品二区| 免费在线观看av网站| 亚洲人成影院在线观看| 黄网站色视频免费观看| av在线私库| 日韩欧美福利视频| 日韩肉感妇bbwbbwbbw| 欧美黄色a视频| 欧美一区二区三区不卡| 日韩成人av影院| 西野翔中文久久精品国产| 亚洲天堂第一页| 日韩精品一区二区三区中文不卡| 蜜桃视频在线观看成人| 久久精品蜜桃| 成人欧美一区二区三区1314| 超碰免费在线公开| 538在线视频| 日本道精品一区二区三区| 精品久久久99| 美女呻吟一区| 色播久久人人爽人人爽人人片视av| 激情无码人妻又粗又大| 影音先锋久久精品| 国产精品久久久999| 国产按摩一区二区三区| 久久一夜天堂av一区二区三区| 亚洲欧洲久久| 天堂在线中文网官网| 91.麻豆视频| 人妻精品久久久久中文字幕| 亚洲天天综合| 国产成人精品视| 亚洲成人中文字幕在线| 欧美高清在线一区二区| 妞干网视频在线观看| 日韩精选视频| 亚洲电影免费观看| 久久久久久久久久97| 免费视频一区二区三区在线观看| 成人国产精品免费视频| 三级毛片在线免费看| 亚洲视频在线一区观看| 爱福利视频一区二区| 麻豆视频久久| 亚洲午夜未满十八勿入免费观看全集| 久久久久久久久久久久久女过产乱| 在线亚洲自拍| 超碰97在线人人| 岛国中文字幕在线| 欧美在线不卡视频| 国产偷人妻精品一区| 亚洲精品成人影院| 国产欧美日韩视频| 成人午夜电影在线观看| 精品久久久一区| 亚洲欧洲日韩综合| 91精品啪在线观看国产18 | 伊人久久综合视频| 国产精品456露脸| 一本一本久久a久久精品综合妖精| 麻豆视频在线看| 精品动漫一区二区三区在线观看| 四虎884aa成人精品| 免费不卡在线视频| 欧美日韩精品免费在线观看视频| 丁香高清在线观看完整电影视频| 日韩一区二区三免费高清| 大地资源高清在线视频观看| 免费不卡在线视频| 丝袜足脚交91精品| 欧美日韩在线精品一区二区三区激情综合 | 日韩av成人在线| 五十路在线观看| 五月综合激情网| 999精品免费视频| 亚洲乱码视频| 久久手机视频| av电影一区| 亚洲欧美在线一区二区| 日本视频免费观看| 久久久久久久精| 别急慢慢来1978如如2| 国产一区日韩| 国产欧美中文字幕| a免费在线观看| 日韩一卡二卡三卡四卡| 九九九久久久久| 国产91丝袜在线播放九色| 全黄性性激高免费视频| 国产精品巨作av| 欧美亚洲一区在线| 国产永久av在线| 欧美日韩在线直播| 在线看的片片片免费| 国产电影一区二区三区| 免费高清一区二区三区| 欧美freesex8一10精品| 欧洲日本亚洲国产区| 国产一区二区影视| 6080日韩午夜伦伦午夜伦| 毛片a片免费观看| 99在线热播精品免费| 精品久久久噜噜噜噜久久图片| 日本一区二区免费高清| 91在线直播亚洲| av剧情在线观看| 夜夜嗨av一区二区三区四区| 国产精品伦一区二区三区| 一二三四区精品视频| 久久偷拍免费视频| 麻豆传媒一区二区三区| 青草网在线观看| 国产一区二区三区网| 国产精品不卡在线观看| 中文字幕日韩欧美在线| 日韩精品久久久久久久| 国产亚洲成av人在线观看导航| www.99r| 精品成人久久| 少妇特黄a一区二区三区| 国产视频网站一区二区三区| 国语自产精品视频在免费| 国产一级在线| 欧美tickling挠脚心丨vk| 国产又粗又爽视频| 亚洲色图在线看| 人妻丰满熟妇aⅴ无码| 裸体在线国模精品偷拍| 精品少妇人妻av免费久久洗澡| 九九在线精品| 国产不卡一区二区在线观看 | 国产精国产精品| 黄色在线免费| 亚洲男人天堂视频| 黑人精品一区二区三区| 欧美视频一二三区| 国产成人自拍视频在线| 成人欧美一区二区三区小说| 特大黑人巨人吊xxxx| 国产乱理伦片在线观看夜一区| 六月激情综合网| 欧美国产高潮xxxx1819| 亚洲成人a**址| 三级精品视频| 成人在线视频网址| 亚洲精品成a人ⅴ香蕉片| 91av视频在线观看| 午夜在线激情影院| 色哟哟入口国产精品| 全色精品综合影院| 精品国产制服丝袜高跟| 亚洲天堂国产精品| 日韩欧美在线第一页| 久久久久久欧美精品se一二三四| 国产精品毛片久久久久久久| 性少妇bbw张开| 91在线免费视频观看| 三级黄色片免费观看| 精品伊人久久久久7777人| 无码少妇一区二区三区芒果| 中文精品在线| 免费av手机在线观看| 在线观看国产精品入口| 亚洲一区二区三区精品在线观看| 亚洲调教一区| 蜜桃av噜噜一区二区三区| 成人h动漫免费观看网站| 97超碰人人看人人 | 天堂av免费在线| 久久免费看少妇高潮| 最新中文字幕视频| 91美女在线视频| 欧美激情 亚洲| 成人精品小蝌蚪| 欧美日韩一区二区三区四区五区六区| 国产在线视视频有精品| 欧美一级特黄aaa| 韩国欧美国产1区| 永久av免费在线观看| 精品亚洲免费视频| 久久综合在线观看| 国产一区二区在线影院| 美女被艹视频网站| 国产91综合网| 欧美图片一区二区| 国产日韩欧美电影| sm捆绑调教视频| 亚洲欧美区自拍先锋| 青娱乐国产在线| 亚洲第一在线综合网站| 欧美a∨亚洲欧美亚洲| 欧美日韩中文在线观看| 精品视频一二三区| 欧美日韩精品电影| 99久久免费国产精精品| 精品国产髙清在线看国产毛片| 日日夜夜精品免费| 亚洲视频999| 久久综合综合久久| 天天综合网站| 欧美一区二区视频97| 韩国精品主播一区二区在线观看| 国产精品美女久久久久av超清| 日韩护士脚交太爽了| 97免费资源站| 一区二区三区韩国免费中文网站| 日韩成人在线资源| 中文精品电影| 噜噜噜久久亚洲精品国产品麻豆| 久久久人人人| 日韩不卡的av| 91蝌蚪porny| 黄色片子在线观看| 性做久久久久久免费观看 | 91蜜桃在线视频| 欧美一区深夜视频| 韩国一区二区三区视频| 精品视频在线观看| 欧美国产一级| 免费看国产一级片| 狠狠色狠狠色综合| 色婷婷在线影院| 亚洲精品五月天| 国产亚洲欧美在线精品| 制服丝袜中文字幕亚洲| 欧美日韩在线精品一区二区三区激情综 | 欧美丝袜第三区| 蜜臀久久精品久久久久| 中文字幕综合一区| 在线人成日本视频| 亚洲影院在线看| 成人精品视频| 黄色一级视频片| 国产一区激情在线| 久久精品三级视频| 亚洲成年人影院| 国产精品视频无码| 亚洲最新av在线| 人人草在线视频| 亚洲一区二区三区四区在线播放| 久久综合色占| av女优在线播放| 国产精品66部| 乱老熟女一区二区三区| 一本一本大道香蕉久在线精品| 国内精品久久久久久久久久 | 久久久水蜜桃| 韩国精品一区二区三区| gogogo高清免费观看在线视频| 99九九99九九九视频精品| 国产真实乱在线更新| 在线观看国产一区二区| 午夜成人鲁丝片午夜精品| 欧美精品生活片| 亚洲伦理网站| 亚洲欧美国产不卡| 乱人伦精品视频在线观看| 精品视频站长推荐| 一区二区三区欧美日| 91麻豆成人精品国产| 正在播放欧美一区| 素人啪啪色综合| 日本高清不卡一区二区三| 久久久成人网| 免费看污黄网站在线观看| 亚洲福利一区二区三区| 午夜免费福利视频| 美女福利精品视频| 国产不卡精品| 亚洲小视频在线播放| 国产在线视频精品一区| 在线免费看av网站| 3atv在线一区二区三区| 1769在线观看| 91精品久久久久久久久久| 91九色精品国产一区二区| 爽爽爽在线观看| 亚洲蜜臀av乱码久久精品蜜桃| 国产免费一区二区三区免费视频| 日韩在线播放一区| 国产精品久久久久久久久久久久久久久 | 亚洲一区中文字幕在线观看| 久久99高清| 国产精品无码av无码| 久久久精品免费网站| 久操视频在线免费观看| 中文字幕欧美专区| 日韩电影免费观看高清完整版在线观看| 亚洲不卡一卡2卡三卡4卡5卡精品| 国产欧美综合一区二区三区| 波多野结衣福利| 在线观看欧美黄色| 日本激情在线观看| 亚洲自拍另类欧美丝袜| 亚洲天堂激情| 亚洲精品成人无码熟妇在线| 欧美午夜电影在线播放| 蜜桃av在线免费观看| 91pron在线| 亚洲综合99| 99自拍偷拍视频| 欧美不卡激情三级在线观看| 老牛影视精品| 日韩精品久久一区二区三区| 美日韩一区二区| 欧美日韩在线观看免费| 日韩高清不卡av| 国产a亚洲精品| 国产 欧美 日本| 91女人视频在线观看| 中文字幕免费视频观看| 久久视频中文字幕| 精品网站aaa| 自拍偷拍21p| 亚洲图片欧美一区| 国产高清一区在线观看| 亚洲xxx大片| 免费视频一区二区三区在线观看| 国产成人免费在线观看视频| 欧美成人一区二区三区片免费| 久久一卡二卡| 日韩av影视| 国产suv精品一区二区883| 久久国产视频一区| 久久视频在线观看免费| 色88888久久久久久影院| 午夜xxxxx| 色婷婷亚洲一区二区三区| 最新超碰在线| 日本一区二区高清视频|