久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

.net中的游魂現(xiàn)象(轉(zhuǎn)自其他博客)

 冷泉閣 2016-11-24

跳出三界外,不在五行中的timer:
在 使用timer的時候,,發(fā)現(xiàn)timer類型對象的作用于比較奇特。一般而言,,在函數(shù)內(nèi)定義的變量,,其作用域不超過函數(shù),,在函數(shù)結(jié)束的時候變量的生命周期就 結(jié)束了,,但是萬事里總會有個一,普遍規(guī)律下總有那么一些例外的東西,,比如說timer,其作用域就不會因函數(shù)的結(jié)束而結(jié)束??疾煲韵率录幚砗瘮?shù),

       private void button1_Click(object sender, EventArgs e)
        {
            System.Timers.Timer t 
= new System.Timers.Timer();
            t.Interval 
= 1000 * 2;
            t.Elapsed 
+= delegate
            {
                MessageBox.Show(System.DateTime.Now.ToString());
            };
            t.Start();
        }

按完button1按鈕后,,timer持續(xù)運行,每隔約2秒就會彈出一個msgbox顯示當(dāng)前時間,,當(dāng)然,因為我們已經(jīng)失去了t這個變量,,表面上也就無法終止這個timer了(也許有辦法終止吧)。對于這種現(xiàn)象,,我推測是三種原因造成的。一,,timer是對windows內(nèi)核對象的包裝,上面這段托管代碼的底層調(diào)用了來自windows的一些內(nèi)核對象,,在超離作用域的時候,沒有對內(nèi)核對象進(jìn)行相應(yīng)的處理,,當(dāng)然這只是推測,我現(xiàn)在沒有精力去證實,。其二:委托原因。其三 :使用了多線程技術(shù),。
考察以下代碼,,

private void button2_Click(object sender, EventArgs e)
        {
            System.Threading.Thread t 
= new System.Threading.Thread(new System.Threading.ThreadStart(delegate() {
                
for (int i = 0; i < 6; i++)
                {
                    System.Threading.Thread.Sleep(
3000);
                    MessageBox.Show(
"I'm in thread");
                }
     
            }));
            t.Start();
            MessageBox.Show(
"end of click");
        }

 

以上兩段代碼,,現(xiàn)象是類似的,我將其稱之為游魂現(xiàn)象——看上變量已經(jīng)死了,,實際上依然存在,原理尚有待研究,。

內(nèi)存泄漏?
t 在它的理論生命外依然存在——在整個程序的生命周期中都存在,,而且在函數(shù)之外的任何地方都沒有變量指向它引用的對象(內(nèi)存),這中現(xiàn)象似乎是內(nèi)存泄漏了,。 然而t內(nèi)執(zhí)行的是我所期望的代碼,一直在為我服務(wù)著,,一直在發(fā)揮著實質(zhì)作用,我也不需要訪問與控制它,,因此沒有造成內(nèi)存浪費,不能稱之為泄漏,,因為它一直 有效、有用,。

小作用域長生命周期!合理而不合禮的現(xiàn)象,!
t的持續(xù)執(zhí)行是我期望的。我只需要一個變量啟動定時器,,以后不需要在任何 地方干涉它,所以我需要一個作用域小的局部變量(如果使用全局變量會遇到重名,、誤修改等問題),根據(jù)程序的表現(xiàn)而看,,在函數(shù)內(nèi)聲明的t可以正常運行,,而且 表現(xiàn)良好,不會被GC回收(使用GC.Collect();GC.WaitForPendingFinalizers();GC.Collect();測 試過),。看起來很理想,,即滿足小作用域的要求,又滿足持續(xù)運行的期望,。然而事情并不美好,這種寫法不合乎C#的“禮制”,,它運行時的行為超出了C#約定的 常規(guī)生命周期。

如何避免,?
如果您確實不想讓t超出function的生命周期繼續(xù)存在,,可以使用“顯式資源回收”,在必要的地方 使用調(diào)用t.Dispose,以下代碼中的timer就不會“游魂”,,該function有約20s的生命期,,20s內(nèi)msgbox會不斷彈出,20s后 就沒有了,。不這樣也失去了timer的意義。


  private void button1_Click(object sender, EventArgs e)
        {
            System.Timers.Timer t 
= new System.Timers.Timer();
            t.Interval 
= 1000 * 2;
            t.Elapsed 
+= delegate
            {
                MessageBox.Show(System.DateTime.Now.ToString());
            };
            t.Start();
            System.Threading.Thread.Sleep(
1000 * 20);
            t.Stop();
        }

using的法力?
1.以下代碼用于測試了using塊中的表現(xiàn):
ui線程被阻塞20s,觀察發(fā)現(xiàn)20s內(nèi)timer沒有執(zhí)行,,可以看出t在離開using塊后被回收了。


private void button4_Click(object sender, EventArgs e)
        {
            
using (System.Timers.Timer t = new System.Timers.Timer())
            {
                t.Interval 
= 1000 * 1;
                t.Elapsed 
+= delegate
                {
                    MessageBox.Show(System.DateTime.Now.ToString());
                };
                t.Start();
            }
            System.Threading.Thread.Sleep(
1000 * 20);
        }

2.再看以下代碼
我給了using約5s的生命周期,,結(jié)果msgbox在5s內(nèi)彈出來幾次,以后就不彈了,,進(jìn)一步證實using的威力,5s后回收了t引用的資源,。

 

        private void button4_Click(object sender, EventArgs e)
        {
            
using (System.Timers.Timer t = new System.Timers.Timer())
            {
                t.Interval 
= 1000 * 1;
                t.Elapsed 
+= delegate
                {
                    MessageBox.Show(System.DateTime.Now.ToString());
                };
                t.Start();
                System.Threading.Thread.Sleep(
1000 * 5);
            }

        }

 
GC又如何?
強(qiáng)制GC回收一下資源,,結(jié)果是msgbox依舊頑固得彈出,可以看出GC沒有回收t的意思,。

        private void button3_Click(object sender, EventArgs e)
        {
            GC.Collect();
            GC.WaitForPendingFinalizers();
            GC.Collect();
            MessageBox.Show(
"Collect function invok complete.");
        }

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報,。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多