c#多線程同步之EventWaitHandle使用

有這麼一個場景,我須要藉助windows剪貼板把數據插入到word域中。windows

實現步驟:多線程

 一、把剪貼板數據保存到變量。測試

 二、使用剪貼板實現咱們的業務。spa

 三、把變量裏的數據存回剪貼板。線程

      可是結果卻使人詫異,百思不得其解。插入到word裏的數據不是咱們想要插入的內容,而是以前剪貼板上的數據。明明第二步一開始就把剪貼板清空了,那舊數據是怎麼插入到word中呢?通過我測試,只要執行第一步,就會插入髒數據。我查了下剪貼板的實現原理,它是使用一塊應用程序共享的內存,爲應用程序之間傳遞數據。code

      從結果上看第一步影響了第二步,爲了避免影響,我想到了使用多線程來解決問題。具體就是開啓一個線程來執行第一步,等執行完畢後,而後主線程再執行後續的步驟。如此,就解決了問題。見源碼: orm

            EventWaitHandle backUpWait = new EventWaitHandle(false, EventResetMode.ManualReset);
            Thread thread = new Thread(() =>
            {
                if (Clipboard.GetData(DataFormats.Text) != null)
                    clipboardText = Clipboard.GetData(DataFormats.Text).ToString();
                if (Clipboard.GetData(DataFormats.Rtf) != null)
                    clipboardRtf = Clipboard.GetData(DataFormats.Rtf).ToString();
                backUpWait.Set();
            });
            thread.Start();
            backUpWait.WaitOne();
            Thread.CurrentThread.SetApartmentState(ApartmentState.STA);
            Clipboard.Clear();
            Clipboard.SetData(System.Windows.Forms.DataFormats.Rtf, null);
            Clipboard.SetData(System.Windows.Forms.DataFormats.Text, null);
            Clipboard.SetData(System.Windows.Forms.DataFormats.Rtf, str_Content);
 

 

源碼解析:我使用了EventWaitHandle類,這個類的層次結構見下圖:

      從圖上看,EventWaitHandle的父類是WaitHandler,有兩個子類,一個是AutoResetEvent,另外一個是ManualResetEvent。咱們使用EventResetMode.ManualReset 手動設置模式,相似於ManualResetEvent類。EventWaitHandle對象有兩種狀態:終止狀態和非終止狀態。在非終止狀態下,某個線程調用其WaitOne方法,阻止此線程繼續執行,也就是處於阻塞狀態。 當一個線程調用Set方法時,其它阻塞的線程被釋放,繼續執行,此時EventWaitHandle處於終止狀態。這就是其工做原理。對象

 
相關文章
相關標籤/搜索