c#多線程同步之EventWaitHandle使用


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

實現步驟:

 1、把剪貼板數據保存到變量。

 2、使用剪貼板實現我們的業務。

 3、把變量里的數據存回剪貼板。

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

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

            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處於終止狀態。這就是其工作原理。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM