有這么一個場景,我需要借助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處於終止狀態。這就是其工作原理。
