2010-01-28 21 views
7

我在做一個拖放到外部應用程序是這樣的:的DoDragDrop凍結WinForms應用程序有時

string[] files = new string[/* */]; 

// get files 

DataObject o = new DataObject(DataFormats.FileDrop, files); 
DoDragDrop(o, DragDropEffects.Copy | DragDropEffects.Move); 

和一些應用程序將需要的文件和前進處理他們和我的應用程序是免費做的東西,但有些應用程序會讓我的應用程序凍結,直到它處理所有文件爲止......有什麼方法可以解決這個問題嗎?我試圖在一個線程中做到這一點,但這並沒有工作得那麼好 - 它根本無法工作......所以,如何讓這段代碼不會掛掉我的應用程序?

回答

3

的.NET Control.DoDragDrop就要到了WIN32 API稱爲..(等待它)一個wapper .. DoDragDrop

所以它具有相同的侷限性。 DoDragDrop只能從調用OleInitialize的線程調用,該線程使線程成爲STA(單線程公寓)類型的線程。

因爲它只能由STA線程使用,並且API設計是同步的,所以您處於目標應用程序處理丟棄通知的擺佈之中。這只是OLE拖放設計的一部分,無法更改。 (OLE拖放實際上是在Windows 3x天內設計的,在線程甚至存在於Windows應用程序中之前)。

所以,你可以也許使這項工作在另一個線程IFF該線程是一個STA線程。您也可能不得不使用互操作來調用非託管的DoDragDrop函數。

+0

嗯,這很有趣,我敢打賭,你是對的,但這並不能解決問題;)我的意思是......我不需要運行DoDragDrop異步...我需要做的就是讓交換數據的部分是異步的...我在某處讀到DataObject將不得不實現一些異步接口,但我現在找不到它...你可能知道我在哪裏可以找到'place'應用程序與其他應用程序交換數據? (使用DoDragDrop ofc) – argh 2010-01-30 17:03:51

+0

數據交換部分位於DoDragDrop內部,因此如果您希望數據交換爲異步,則必須將DoDragDrop放在另一個線程上。它必須是一個STA線程。你知道如何強制一個線程在.NET中成爲STA嗎? – 2010-01-30 19:38:32

+0

那麼......糾正我,如果我錯了,但如果我有: [STAThread] static void Main(string [] parameters) 然後它正在STA線程中運行,對吧? – argh 2010-01-30 22:30:58

0

它會一直凍結,但延遲對於小文件並不明顯。檢查出this answer