有這麼一個場景,我須要藉助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處於終止狀態。這就是其工做原理。對象