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

你不知道的陷阱:C#委托和事件的困惑

開發(fā) 后端
C語言因?yàn)楹瘮?shù)指針獲得了極強(qiáng)的動(dòng)態(tài)性,因?yàn)槟憧梢酝ㄟ^給函數(shù)指針賦值并動(dòng)態(tài)改變其行為,我曾在單片機(jī)上寫的一個(gè)小系統(tǒng)中,任務(wù)調(diào)度機(jī)制玩的就是函數(shù)指針。

一. 問題引入

通常,一個(gè)C語言學(xué)習(xí)者登堂入室的標(biāo)志就是學(xué)會(huì)使用了指針,而成為高手的標(biāo)志又是“玩轉(zhuǎn)指針”。指針是如此奇妙,通過一個(gè)地址,可以指向一個(gè)數(shù),結(jié)構(gòu)體,對(duì)象,甚至函數(shù)。最后的一種函數(shù),我們稱之為“函數(shù)指針”(和“指針函數(shù)”可不一樣?。┚拖袢缦碌拇a:

  1. int func(int x); /* 聲明一個(gè)函數(shù) */ 
  2.     int (*f) (int x); /* 聲明一個(gè)函數(shù)指針 */ 
  3.    f=func; /* 將func函數(shù)的首地址賦給指針f */ 

C語言因?yàn)楹瘮?shù)指針獲得了極強(qiáng)的動(dòng)態(tài)性,因?yàn)槟憧梢酝ㄟ^給函數(shù)指針賦值并動(dòng)態(tài)改變其行為,我曾在單片機(jī)上寫的一個(gè)小系統(tǒng)中,任務(wù)調(diào)度機(jī)制玩的就是函數(shù)指針。

在.NET時(shí)代,函數(shù)指針有了更安全更優(yōu)雅的包裝,就是委托。而事件,則是為了限制委托靈活性引入的新“委托”(之所以為什么限制,后面會(huì)談到)。同樣,熟練掌握委托和事件,也是C#登堂入室的標(biāo)志。有了事件,大大簡化了編程,類庫變得前所未有的開放,消息傳遞變得更加簡單,任何熟悉事件的人一定都深有體會(huì)。

但你也知道,指針強(qiáng)大,高性能,帶來的就是危險(xiǎn),你不知道這個(gè)指針是否安全,出了問題,非常難于調(diào)試。事件和委托這么好,可是當(dāng)你寫了很多代碼,完成大型系統(tǒng)時(shí),心里是不是總覺得怪怪的?有當(dāng)年使用指針時(shí)類似的感覺?

如果是的話,請(qǐng)看如下的問題:

1.若多次添加同一個(gè)事件處理函數(shù)時(shí),觸發(fā)時(shí)處理函數(shù)是否也會(huì)多次觸發(fā)?

2.若添加了一個(gè)事件處理函數(shù),卻執(zhí)行了兩次或多次”取消事件“,是否會(huì)報(bào)錯(cuò)?

3.如何認(rèn)定兩個(gè)事件處理函數(shù)是一樣的? 如果是匿名函數(shù)呢?

4.如果不手動(dòng)刪除事件函數(shù),系統(tǒng)會(huì)幫我們回收嗎?

5.在多線程環(huán)境下,掛接事件時(shí)和對(duì)象創(chuàng)建所在的線程不同,那事件處理函數(shù)中的代碼將在哪個(gè)線程中執(zhí)行?

6.當(dāng)代碼的層次復(fù)雜時(shí),開放委托和事件是不是會(huì)帶來更大的麻煩?

列下這些問題,下面就讓我們討論這些”尖酸刻薄“的問題。

#p#

二. 事件訂閱和取消問題

我們考慮一個(gè)典型的例子:加熱器,加熱器內(nèi)部加熱,在達(dá)到溫度后通知外界”加熱已經(jīng)完成“。 嘗試寫下如下測(cè)試類:

  1. ///   
  2.    /// 熱水器  
  3.    ///   
  4.    public class Heater  
  5.    {  
  6.        public event EventHandler OnBoiled;  
  7.        private  void RasieBoiledEvent()  
  8.        {  
  9.            if(OnBoiled==null)  
  10.            {  
  11.                Console.WriteLine("加熱完成處理訂閱事件為空");  
  12.            }  
  13.            else 
  14.            {  
  15.                OnBoiled(thisnew EventArgs());  
  16.            }  
  17.        }  
  18.        private Thread heatThread;  
  19.        public void Begin()  
  20.        {  
  21.            heatTime = 5;  
  22.            heatThread = new Thread(new ThreadStart(Heat));  
  23.            heatThread.Start();  
  24.            Console.WriteLine("加熱器已經(jīng)開啟", heatTime);  
  25.    
  26.        }  
  27.        private int heatTime;  
  28.        private void Heat()  
  29.        {  
  30.            while (true)  
  31.            {  
  32.                Console.WriteLine("加熱還需{0}秒", heatTime);  
  33.    
  34.                if (heatTime == 0)  
  35.                {  
  36.                    RasieBoiledEvent();  
  37.                     return;  
  38.                }  
  39.                heatTime--;  
  40.                Thread.Sleep(1000);  
  41.    
  42.            }  
  43.        }  
  44.    } 

OK,簡單了,下面是main函數(shù):

  1. class Program  
  2.     {  
  3.         static void Main(string[] args)  
  4.         {  
  5.             var test = new Heater();  
  6.             test.OnBoiled += TestOnBoiled;  
  7.             test.OnBoiled += TestOnBoiled;  
  8.             test.Begin();  
  9.             Console.ReadKey();  
  10.         }  
  11.         static void TestOnBoiled(object sender, EventArgs e)  
  12.         {  
  13.             Console.WriteLine("Hello事件被調(diào)用");  
  14.         }  
  15.     } 

我們有意將事件掛載了兩次,看看執(zhí)行效果:

你可能不知道的陷阱:C#委托和事件的困惑

很明顯,如果多次掛載同一事件處理函數(shù),函數(shù)將會(huì)執(zhí)行多次。

這就是第一個(gè)問題的答案。

  1. 接下來,我們將上文中main函數(shù)中紅色代碼替換成如下蛋疼的代碼:  
  2. test.OnBoiled += TestOnBoiled;  
  3. test.OnBoiled -= TestOnBoiled;  
  4. test.OnBoiled -= TestOnBoiled; 

在實(shí)際開發(fā)中,這種情況是很普遍的,誰都有可能取消訂閱多次,結(jié)果如何呢?

你可能不知道的陷阱:C#委托和事件的困惑

在執(zhí)行過程中,刪除兩次事件沒有報(bào)錯(cuò),但當(dāng)觸發(fā)事件時(shí),由于事件訂閱列表為空,所以,第二個(gè)問題的答案:多次刪除同一事件是不會(huì)報(bào)錯(cuò)的,即使事件只被訂閱了一次。若出現(xiàn)訂閱三次,取消訂閱兩次時(shí),依舊執(zhí)行一次。

這個(gè)事情是好理解的,事件列表,實(shí)際上就是List,最簡單的增刪問題。

#p#

三. 有了匿名函數(shù)后?

自從學(xué)習(xí)匿名函數(shù)后,筆者就特別喜歡用它,除非代碼量特別長,否則十行之內(nèi)的事件訂閱,我都會(huì)用匿名函數(shù)。可是事情變得有意思了,寫了匿名函數(shù)后,幾乎沒人記得取消訂閱,那么,發(fā)生了什么事情呢?

和上次一樣,我們將前面紅色代碼改成下面的樣子:

  1. test.OnBoiled += (s, e) => Console.WriteLine("加熱完成事件被調(diào)用");test.OnBoiled -= (s, e) => Console.WriteLine("加熱完成事件被調(diào)用");test.Bein(); 

Resharper直接給我畫了灰線,如下圖:

你可能不知道的陷阱:C#委托和事件的困惑

我估計(jì)情況不太樂觀,執(zhí)行之后:

你可能不知道的陷阱:C#委托和事件的困惑

果然!加熱完成事件還是被調(diào)用了,也就是說,看著形式完全一致的兩個(gè)匿名函數(shù),編譯器生成的方法簽名是不一致的,根本就是兩個(gè)不同的函數(shù)。因此,匿名函數(shù)完全沒法取消訂閱! 這是第三個(gè)問題的答案。

事件不能被取消訂閱!這下可慘了,我真的要取消怎么辦?沒辦法,只能乖乖的寫完整的事件函數(shù)。匿名方法雖好,千萬別用過頭。

但是,真正麻煩的問題來了,一個(gè)復(fù)雜的動(dòng)態(tài)系統(tǒng)中,一定隨時(shí)會(huì)有大量的對(duì)象生成和銷毀,你也一定會(huì)給它訂閱一些事件,當(dāng)你用匿名函數(shù)后,這些函數(shù)是不是就像死神一樣,一直掐著你的脖子? 如果事件處理函數(shù)涉及重要操作,比如給對(duì)方付款,執(zhí)行多次你是不是就要哭死了?

#p#

四. 垃圾回收和事件

垃圾回收機(jī)制攙和進(jìn)來后,故事變的更有意思了。

我“殷切”的希望,垃圾回收器會(huì)幫我解決第三節(jié)最后一段談到的問題,幫我收拾掉那些函數(shù),那真實(shí)的情況呢?我們做個(gè)試驗(yàn):

同樣的,替換掉紅色部分:

  1. test.OnBoiled += (s, e) => Console.WriteLine("加熱完成事件被調(diào)用");  
  2. test=new Heater();  
  3. GC.Collect();  //強(qiáng)制垃圾回收實(shí)際上可有可無  
  4. test.Bein(); 

下面是執(zhí)行結(jié)果:

你可能不知道的陷阱:C#委托和事件的困惑

哈,起碼在我更新了對(duì)象引用,new了新對(duì)象之后,原來的匿名事件確實(shí)沒有了??磥砭幾g器還是夠意思的。

可是,多數(shù)實(shí)際開發(fā)情況中,我們很少直接new一個(gè)對(duì)象覆蓋掉原來的引用。而是重新new了一個(gè)對(duì)象出來。這種情況的代碼如下

  1. test.OnBoiled += (s, e) => Console.WriteLine("加熱完成事件被調(diào)用");  
  2.             var heaters = new List() { test, test };  
  3.             heaters.Clear();  
  4.             test.Begin();  
  5.             test = null;  
  6.             GC.Collect(); 

執(zhí)行結(jié)果如下圖:

你可能不知道的陷阱:C#委托和事件的困惑

這種情況下,test即使被賦值為null,事件還是會(huì)乖乖執(zhí)行,因?yàn)槭悄涿瘮?shù),你也沒法取消訂閱,而GC強(qiáng)制收集也沒用! 這就是我們真實(shí)場(chǎng)景中最可怕的事情,你認(rèn)為它已經(jīng)消失了,可是它還掛在事件上!

其實(shí)這里有個(gè)破綻:Heater類里開了線程,我即使賦值為null,線程肯定還沒有被銷毀,事件確實(shí)可能會(huì)執(zhí)行,時(shí)間所限,我沒有嘗試在寫一個(gè)類測(cè)試不開線程的情況,有興趣的讀者可以幫忙試一試。

而且,經(jīng)過我查閱資料,當(dāng)你的對(duì)象訂閱了外部的事件,而又沒有取消訂閱,那么該對(duì)象是不會(huì)被GC回收的!這會(huì)造成很恐怖的問題,產(chǎn)生了幾千萬個(gè)對(duì)象沒法被回收。可是,匿名函數(shù)讓我怎么么取消訂閱?!

所以我們得到了結(jié)論,除非確實(shí)是一般場(chǎng)景,比如界面開發(fā)的window,生成了一直存在,或者在應(yīng)用程序關(guān)閉時(shí)回收,否則少用匿名函數(shù)吧!記得取消事件訂閱!否則會(huì)是非常麻煩的事情!

#p#

五.高潮: 多線程和事件

多線程本來就是程序員頭疼的問題,筆者在多線程知識(shí)上只是入門,沒開發(fā)過高并發(fā)系統(tǒng),倒是經(jīng)常用并行庫加速算法執(zhí)行。 讓我們看看多線程和事件兩個(gè)最難搞的東西糾纏在一起時(shí)是個(gè)什么樣子。

一種常見的場(chǎng)景,是事件處理很耗時(shí),比如執(zhí)行長時(shí)間的IO操作,或者進(jìn)行了復(fù)雜的數(shù)學(xué)計(jì)算,我們不想影響主線程,那么你想當(dāng)然的會(huì)通過多線程的方法解決。

創(chuàng)建對(duì)象的線程,一般是主線程(或者UI線程),那么,怎么讓事件處理函數(shù)在另外一個(gè)線程執(zhí)行呢? 你真的保證處理函數(shù)在另外一個(gè)線程中執(zhí)行了?異步調(diào)用?好辦法,不過我們此處不說這個(gè)。

//////////////////**************///////////////////////////

修正:經(jīng)過了重新的測(cè)試,發(fā)現(xiàn)我的測(cè)試用例寫的有問題,為了讓Heater類自己觸發(fā)事件,我在內(nèi)部寫了一個(gè)新線程,導(dǎo)致測(cè)試不準(zhǔn)確。

結(jié)論應(yīng)該是: 不論是不是在多線程環(huán)境下,事件處理函數(shù)一定在觸發(fā)事件位置所在的線程中,和事件訂閱者的創(chuàng)建線程,訂閱事件時(shí)所在的線程無關(guān)。。。。。。我第五節(jié)的內(nèi)容,有多半都是錯(cuò)的。。。。

因此,若是觸發(fā)事件所在線程是主線程的話,基本上只能用我提出的第二種做法,通過事件內(nèi)部使用線程池來執(zhí)行了。感謝 West Continent 的討論。

/////////////////*************/////////////////////

1. 新建線程方法:

初學(xué)者會(huì)這么做:

  1. test.OnBoiled += (s, e) =>  
  2.                 {  
  3.                     var newThread = new Thread(  
  4.                         new ThreadStart(  
  5.                             () =>  
  6.                                 {  
  7.                              Thread.Sleep(2000); //模擬長時(shí)間操作  
  8.                                     Console.WriteLine("總算把熱好的水加到了暖瓶里");  
  9.                                 }));  
  10.                     newThread.Start();  
  11.                 };             
  12.             test.Begin(); 

我的手指還是選擇了匿名函數(shù),用起來真爽,這種情況下,顯然事件處理函數(shù)所在線程和主線程不一樣。

可是,稍微有點(diǎn)基礎(chǔ)的人就知道,當(dāng)事件被頻繁觸發(fā)時(shí),線程就會(huì)被頻繁生成,線程同樣是非常昂貴的系統(tǒng)資源,更何況,線程的啟動(dòng)時(shí)間是不確定的,可能會(huì)耽誤大事。這不是個(gè)好方案。

2. 線程池

采用.NET 4.0的線程池試試看,代碼如下:

  1. var mainThread = Thread.CurrentThread;  
  2.             test.OnBoiled += (s, e) =>  
  3.                 {  
  4.                     ThreadPool.QueueUserWorkItem((d) =>  
  5.                         {  
  6.                             Thread.Sleep(2000); //模擬長時(shí)間操作  
  7.                             Console.WriteLine("總算把熱好的水加到了暖瓶里");  
  8.                             if (Thread.CurrentThread != mainThread)  
  9.                             {  
  10.                                 Console.WriteLine("兩者執(zhí)行的是不同的線程");  
  11.                             }  
  12.                             else 
  13.                             {  
  14.                                 Console.WriteLine("兩者執(zhí)行的是相同的線程");  
  15.                             }  
  16.                         });  
  17.                 };  
  18.             test.Begin(); 

我們通過緩存主線程,并比較處理函數(shù)中的線程,得到結(jié)果如下:

你可能不知道的陷阱:C#委托和事件的困惑

確實(shí),采用線程池時(shí),會(huì)是兩個(gè)是不一樣的線程,線程池由于內(nèi)部做了管理,因此可以有效的利用線程,避免瘋狂新開線程造成的嚴(yán)重的性能問題。

可是,我覺得還是麻煩,尤其是有多種事件時(shí),挨個(gè)寫線程池還是太麻煩了。那么,我們是不是有兩種方案?

一種是將構(gòu)造函數(shù)寫在一個(gè)新線程中,另外一種是將事件訂閱函數(shù)寫在新線程中,兩者會(huì)發(fā)生怎樣的情況呢?

3. 對(duì)象的構(gòu)造函數(shù)處在新線程時(shí):

如下測(cè)試代碼:

  1. var mainThread = Thread.CurrentThread;  
  2.             var autoResetEvent = new AutoResetEvent(false);  //通過信號(hào)機(jī)制保證對(duì)象首先被創(chuàng)建  
  3.             ThreadPool.QueueUserWorkItem((d) =>  
  4.                 {  
  5.                     test=new Heater();  
  6.                     autoResetEvent.Set();  
  7.                 });  
  8.             autoResetEvent.WaitOne();  
  9.             test.OnBoiled += (s, e) => Console.WriteLine(Thread.CurrentThread != mainThread ? "兩者執(zhí)行的是不同的線程" : "兩者執(zhí)行的是相同的線程");  
  10.             test.Begin(); 

代碼值得一提的是,為了保證對(duì)象被首先創(chuàng)建,采用了信號(hào)機(jī)制實(shí)現(xiàn)線程同步,當(dāng)創(chuàng)建后,主線程才會(huì)往下執(zhí)行,否則會(huì)拋出空引用的異常.

結(jié)果如下:

你可能不知道的陷阱:C#委托和事件的困惑

可見: 主線程稱為Main, 若對(duì)象構(gòu)造函數(shù)在B線程執(zhí)行,事件不在主線程中執(zhí)行。那是不是在B線程中執(zhí)行呢?暫時(shí)還不知道。

4. 對(duì)象的事件訂閱函數(shù)處在新線程時(shí):

在另外一個(gè)線程里創(chuàng)建對(duì)象是更麻煩的,你要解決線程同步問題,惡心不,哈哈。

那么,若訂閱事件的代碼在線程B時(shí),情況是怎樣的呢?

  1. var mainThread = Thread.CurrentThread;   
  2.             ThreadPool.QueueUserWorkItem((d) =>  
  3.                 {  
  4.                     var bThread = Thread.CurrentThread;  
  5.                     test.OnBoiled += (s, e) =>  
  6.                         {  
  7.                             if(Thread.CurrentThread == mainThread )  
  8.                                 Console.WriteLine("事件在主線程中執(zhí)行");  
  9.                             else if (bThread==Thread.CurrentThread)  
  10.                             {  
  11.                                 Console.WriteLine("事件在訂閱事件的線程B中執(zhí)行");  
  12.                             }  
  13.                             else 
  14.                             {  
  15.                                 Console.WriteLine("事件在第三個(gè)線程中執(zhí)行");  
  16.                             }  
  17.                         };  
  18.                 });  
  19.    
  20.             test.Begin(); 

結(jié)論:

你可能不知道的陷阱:C#委托和事件的困惑

說實(shí)話,我看到這個(gè)場(chǎng)景的時(shí)候大吃一驚,居然執(zhí)行事件的代碼不在主線程,不在訂閱事件的線程,而在另外一個(gè)第三者線程!這可能就是線程池的無敵之處吧,它連事件訂閱函數(shù)都給托管了!真是碉堡了??!

不過,管它是什么線程里執(zhí)行,反正我主線程是不會(huì)被堵塞了,哈哈.

六.結(jié)語

本來想今天把最后一個(gè)問題都解決的,可是時(shí)間實(shí)在太晚,而且文章已經(jīng)夠長了。不妨最后一個(gè)問題,“在復(fù)雜軟件環(huán)境下,如何理性正確的使用委托和事件”放在第二部分吧。有些問題我也沒搞清,在做實(shí)驗(yàn)的情況下,才逐漸接近結(jié)論。 寫完這篇文章,我深有收獲。

其實(shí),按照慣例,應(yīng)該把IL代碼好好搞出來給大家看才算是“專業(yè)”的選擇,不過我確實(shí)不懂IL,就不拿出來丟人了,高手們請(qǐng)自行腦補(bǔ)。

本文介紹了C#的委托和事件的訂閱和取消訂閱,并在匿名函數(shù)和多線程兩個(gè)環(huán)境下討論了一些問題。如果你覺得這篇文章對(duì)你有幫助,請(qǐng)點(diǎn)一下推薦,若有任何問題,歡迎留言討論,共同學(xué)習(xí)。

測(cè)試代碼見附件,請(qǐng)將不同Region的代碼解開注釋進(jìn)行測(cè)試。

原文鏈接:http://www.cnblogs.com/buptzym/archive/2013/03/15/2962300.html

責(zé)任編輯:張偉 來源: 博客園
相關(guān)推薦

2014-12-08 10:39:15

2020-06-12 09:20:33

前端Blob字符串

2020-07-28 08:26:34

WebSocket瀏覽器

2009-12-10 09:37:43

2022-10-13 11:48:37

Web共享機(jī)制操作系統(tǒng)

2021-02-01 23:23:39

FiddlerCharlesWeb

2011-09-15 17:10:41

2010-08-23 09:56:09

Java性能監(jiān)控

2009-08-18 10:54:17

C#事件和委托

2020-08-05 12:17:00

C語言代碼分配

2022-11-04 08:19:18

gRPC框架項(xiàng)目

2020-09-15 08:35:57

TypeScript JavaScript類型

2021-10-17 13:10:56

函數(shù)TypeScript泛型

2021-12-29 11:38:59

JS前端沙箱

2021-12-22 09:08:39

JSON.stringJavaScript字符串

2015-06-19 13:54:49

2020-08-11 11:20:49

Linux命令使用技巧

2012-11-23 10:57:44

Shell

2009-08-27 16:53:01

C#委托C#事件

2024-06-28 10:19:02

委托事件C#
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

亚洲精品国产首次亮相| 成人国产一区| 久久精品视频一区二区三区| 国产精品视频区| 日本中文在线视频| 女同一区二区三区| 在线免费观看日本欧美| 福利在线小视频| 日韩a在线观看| 激情成人综合网| 午夜剧场成人观在线视频免费观看| 实拍女处破www免费看| 99tv成人影院| 色综合久久中文字幕| 青青视频免费在线| 成人高清网站| 99精品久久99久久久久| 91视频国产精品| 日本免费成人网| 欧美伦理影视网| 野花国产精品入口| 久久久精品网站| 天天操天天爽天天射| av免费在线网站| 国产午夜精品美女毛片视频| 成人区精品一区二区| 夜夜骚av一区二区三区| 国产成人手机高清在线观看网站| 91精品国产综合久久久久久久| 99r国产精品视频| 自拍偷拍校园春色| 欧美日韩激情| 欧美在线三级电影| av免费观看网| 天堂a√中文在线| 粉嫩在线一区二区三区视频| 91精品免费看| 国产女优在线播放| 欧美综合二区| 91av视频在线| 波多野结衣 在线| 136福利精品导航| 欧美一区三区四区| 亚洲午夜激情影院| 日韩有码欧美| 欧美日本一道本在线视频| 五月婷婷狠狠操| 日韩久久一区二区三区| 欧美日韩在线看| 奇米影视亚洲色图| 波多野结衣在线观看| 93久久精品日日躁夜夜躁欧美| 97人人澡人人爽| 国产免费一区二区三区最新不卡 | 黄色一级片国产| 国产传媒在线播放| 亚洲精品自拍动漫在线| 中文字幕免费高| 国产秀色在线www免费观看| 中文字幕在线观看一区二区| 亚洲一区二区三区免费观看| 91露出在线| 中文字幕日韩一区二区| 男女h黄动漫啪啪无遮挡软件| 黄色小网站在线观看| 亚洲日本在线看| 亚洲国产一二三精品无码 | 不用播放器的免费av| 欧美一级免费| 欧美一区二区免费视频| 久久久久亚洲av无码网站| 国产h片在线观看| 亚洲成年人影院| 男人日女人bb视频| 国产欧美自拍| 日韩一二在线观看| av直播在线观看| 成人羞羞网站| 萌白酱国产一区二区| 国产一级视频在线| 男女av一区三区二区色多| 国产91免费看片| 国产熟女一区二区丰满| caoporn国产精品| 日韩国产伦理| 在线观看午夜av| 欧美日韩综合视频| 久久手机在线视频| 在线观看的黄色| 欧美日本免费一区二区三区| 精品伦一区二区三区| 美女久久99| 久久最新资源网| 天天操天天爽天天干| 亚洲精品午夜av福利久久蜜桃| 欧美激情国产日韩精品一区18| 中文字幕亚洲精品一区| 精品一区二区在线播放| 日韩美女免费视频| 国产精品探花视频| 免费在线视频一区| www.一区二区三区| www亚洲人| 亚洲成人自拍一区| 9久久婷婷国产综合精品性色 | 视频一区在线视频| 3d精品h动漫啪啪一区二区| 亚洲日本中文字幕在线| 亚洲免费大片在线观看| 粉嫩虎白女毛片人体| 成人午夜三级| 美女福利精品视频| 免费在线观看av的网站| www.成人在线| 裸体裸乳免费看| 欧美日韩国产网站| 亚洲精品视频网上网址在线观看| 亚洲二区在线播放| 欧美aaaaa成人免费观看视频| 国产精品免费一区二区三区观看| 日本欧美在线视频免费观看| 色哟哟一区二区| 一级欧美一级日韩片| 午夜日韩av| 国产日韩在线视频| 成年人免费在线视频| 午夜国产不卡在线观看视频| 黄色a级三级三级三级| 日产精品一区二区| 热门国产精品亚洲第一区在线| 亚洲黄色一级大片| 丰满放荡岳乱妇91ww| 中文一区一区三区免费| 日韩不卡在线| 亚洲天堂av综合网| 手机看片久久久| 久久综合色8888| 六月婷婷在线视频| 激情小说亚洲色图| 97视频免费在线观看| 丰满少妇在线观看bd| 亚洲精品福利视频网站| 亚洲一区二区偷拍| 希岛爱理一区二区三区| 成人网在线免费看| 欧美激情二区| 欧美精品99久久久**| 日本少妇aaa| 精品在线免费视频| 日韩国产精品毛片| 伊人久久大香线蕉av超碰| 欧美日韩第一视频| 午夜美女福利视频| 亚洲va韩国va欧美va| 影音先锋黄色资源| 久久久久91| 日韩区国产区| 亚洲精品无播放器在线播放| 久热精品视频在线观看| 亚洲第一免费视频| 午夜激情一区二区三区| av中文字幕免费观看| 久久久久久久欧美精品| 日韩中文字幕一区二区| 91国拍精品国产粉嫩亚洲一区| 中文字幕亚洲欧美一区二区三区 | 成人开心激情| 中文字幕日韩精品有码视频| 国产精品一区二区av白丝下载 | 欲色天天网综合久久| 亚洲天堂中文字幕在线| 一区二区三区欧美激情| 激情婷婷综合网| 欧美色图激情小说| 亚洲xxxx3d| www日韩tube| 欧美一级夜夜爽| 亚洲 欧美 视频| 国产精品色眯眯| 欧美激情一区二区三区p站| 久久国产免费| 2021狠狠干| 免费看久久久| 国产欧美精品久久久| 色操视频在线| 亚洲网站在线看| 精品久久国产视频| 一本到不卡精品视频在线观看| 你懂得在线观看| 波多野洁衣一区| 狠狠精品干练久久久无码中文字幕 | 黄色国产在线观看| 久久激情五月激情| 国产在线播放观看| 91蜜臀精品国产自偷在线 | 青娱乐精品在线| 99精品视频免费观看| 亚洲欧美日产图| 国产精品极品美女在线观看| 久久精品国产久精国产一老狼| 日本激情视频网站| 欧美嫩在线观看| 天天综合网久久综合网| 亚洲精品网站在线观看| 天天躁夜夜躁狠狠是什么心态| 成人免费毛片app| a在线观看免费视频| av成人毛片| 精品人妻大屁股白浆无码| 欧美精品一区二区三区中文字幕| 亚洲aaaaaa| 蜜桃精品在线| 欧美亚洲第一区| 三级在线观看| 欧美成人在线直播| 91亚洲国产成人精品一区| 第一福利永久视频精品| 久久久久亚洲AV| 亚洲色欲色欲www在线观看| 欧美三级视频网站| 久久综合中文字幕| 7788色淫网站小说| 国产成人精品免费| 6080国产精品| 九九国产精品视频| 欧美第一页浮力影院| 噜噜噜躁狠狠躁狠狠精品视频 | 日韩精品一二三四| 国产免费黄视频| 亚洲乱亚洲高清| 青青草视频在线视频| 亚洲色图国产| 国产精品乱码一区二区三区| 伊人久久综合网另类网站| 国产精品久久久久久久久久久不卡 | 中文字幕亚洲乱码| 日韩精品免费专区| 可以免费在线看黄的网站| 欧美亚洲网站| 日本黄色三级大片| 久久精品日产第一区二区 | 亚洲免费视频一区| 欧美一区二区三区高清视频| 三区精品视频观看| 99久久99九九99九九九| 国产日韩在线视频| 国产精品视频首页| 91色视频在线观看| 精品国产鲁一鲁****| 91精品国自产在线观看| 日韩高清一区| 国产日韩一区欧美| 亚洲精品推荐| 青青草成人网| 我要色综合中文字幕| 99久久99| 日韩有码一区| 91久久久久久久久久久| 成人免费观看49www在线观看| 成人免费黄色网| 一区二区三区视频免费视频观看网站 | 成人影院中文字幕| 久久一区二区三区av| 经典一区二区| 波多野结衣三级在线| 欧美在线免费| 免费在线激情视频| 蜜桃久久久久久久| 久久精品无码一区二区三区毛片| 国产成人免费视频网站 | 91精品国产色综合久久不卡98口| 中文在线免费视频| 国产欧美精品xxxx另类| 久久久久久爱| 老牛影视免费一区二区| 久久亚洲在线| 黄色一级视频在线播放| 日本三级亚洲精品| 在线成人精品视频| 丝袜脚交一区二区| 一二三级黄色片| 99久久er热在这里只有精品15| 国产精成人品免费观看| 亚洲综合精品自拍| 久久永久免费视频| 日韩一区国产二区欧美三区| 天堂v在线观看| 色婷婷综合成人av| 成人免费观看在线观看| 国产精品网红福利| 好吊妞视频这里有精品| 日韩亚洲视频在线| 亚洲午夜精品久久久久久app| 久久精品网站视频| 懂色av中文一区二区三区 | 亚洲伦在线观看| 亚洲天堂一区在线观看| 91精品国产综合久久福利软件| 三级做a全过程在线观看| 久久中文精品视频| 午夜无码国产理论在线| 国产偷国产偷亚洲高清97cao| 青青草97国产精品麻豆| 精品无码一区二区三区在线| 精品一区二区三区在线观看| 久久久亚洲av波多野结衣| 一区二区三区在线免费播放| 一区二区三区麻豆| 亚洲精品久久久久久久久| 国内精品久久久久久野外| 国产91亚洲精品| 精品国产一区二区三区成人影院 | 久久精品网址| 污片免费在线观看| 亚洲另类在线一区| 91成品人影院| 国产一区二区欧美日韩| 麻豆mv在线看| 国产精品三区www17con| 欧美va天堂| 亚洲妇熟xx妇色黄蜜桃| 欧美国产1区2区| 老熟妇仑乱一区二区av| 亚洲精品av在线播放| 日本在线观看高清完整版| 91美女片黄在线观| 国产精品久久观看| 日韩大片一区二区| 国产嫩草影院久久久久| 福利网址在线观看| 日韩久久精品电影| 亚洲女同志freevdieo| 国产精品一区二区欧美黑人喷潮水| 亚洲精品一区二区妖精| 亚洲人视频在线| 国产精品三级av在线播放| 天堂av免费在线观看| 亚洲美女喷白浆| 欧美电影h版| 欧美在线激情| 日韩国产欧美一区二区三区| x88av在线| 欧美日本一区二区| 黄网站视频在线观看| 91青草视频久久| 91精品99| 色婷婷狠狠18禁久久| 欧美一级鲁丝片| 欧美亚洲日本国产| 国产中文在线| 精品国产凹凸成av人网站| 日本人妻熟妇久久久久久 | 国产麻豆乱码精品一区二区三区| 欧美精品一线| 蜜臀av粉嫩av懂色av| 欧美日韩国产精品专区| 色视频在线观看| 国产ts一区二区| 日韩一区二区在线| 五月六月丁香婷婷| 亚洲一级二级三级| 日本精品久久久久久| 日韩免费观看视频| 日韩精品中文字幕第1页| av中文字幕网址| 亚洲黄色小说网站| 蜜桃av噜噜一区二区三区麻豆| 国语自产精品视频在线看抢先版图片 | 国产精品入口| 免费网站在线观看黄| 亚洲美女在线一区| 网站黄在线观看| 国产精品pans私拍| 亚洲国产精品久久久久蝴蝶传媒| 肉丝美足丝袜一区二区三区四| 午夜婷婷国产麻豆精品| 国产黄在线观看| 91日本视频在线| 国产欧美大片| 日本黄区免费视频观看| 欧美成人精品福利| www.成人爱| 国产成人三级视频| 2欧美一区二区三区在线观看视频 337p粉嫩大胆噜噜噜噜噜91av | 免费在线高清av| 91在线网站视频| 国产女优一区| 黄色一级大片在线免费观看| 亚洲国产精品女人久久久| 欧美日一区二区三区| 久久久久久久9| 亚洲国产精品av| 国产 日韩 欧美 精品| 国产精品美乳一区二区免费| 亚洲欧美一级二级三级| 老熟妇一区二区| 精品国产污污免费网站入口| 亚洲人免费短视频| 可以看毛片的网址| 国产成人一区二区精品非洲|