2011-03-08 46 views
7

我正在下載文件,並且只有在下載完成後纔想執行安裝。我該如何做到這一點?看起來像FileSystemWatcher的onCreate事件會做到這一點,但這發生在不同的線程,是否有一種簡單的方法來強制等待的部分發生在同一個線程。如何強制FileSystemWatcher等待文件下載?

代碼我到目前爲止

FileSystemWatcher w = new FileSystemWatcher(@"C:/downloads"); 
w.EnableRaisingEvents = true; 
w.Created += new FileSystemEventHandler(FileDownloaded); 

static void FileDownloaded(object source, FileSystemEventArgs e) 
{ 
    InstallMSI(e.FullPath); 
} 

我看着和SynchronizingObject的WaitForChangedResult但沒有得到穩固的工作樣本。

+0

如何下載文件?示例代碼很好。 – unholysampler 2011-03-08 20:26:30

+0

下載正在UI中完成..該代碼將使這個問題變得凌亂。我只能說當這段代碼被觸發時,下載操作已經開始 – satyajit 2011-03-08 20:29:13

+0

[FileSystemWatcher Work is Done?]的可能重複(http://stackoverflow.com/questions/4662893/filesystemwatcher-work-is-done ) – 2011-03-08 20:36:27

回答

2

一種技術是下載到臨時目錄,然後將它移動到C:/下載完成後,它將移動到C:/下載。

+0

我如何知道下載是否完成,即何時觸發移動? – satyajit 2011-03-08 20:34:20

+0

取決於你如何下載它。代碼是什麼樣的? – 2011-03-08 20:40:28

+2

下載完成後請執行x操作。那這就是問題! – ukhardy 2011-03-08 20:50:00

2

如果您使用WebClient進行下載,您可以使用設置客戶端的DownloadFileCompleted事件處理程序。
如果你這樣做,你也可以使用client.DownloadFileAsync()來異步下載。

14

嘗試:

FileInfo fInfo = new FileInfo(e.FullPath); 
while(IsFileLocked(fInfo)){ 
    Thread.Sleep(500);  
} 
InstallMSI(e.FullPath); 


static bool IsFileLocked(FileInfo file) 
{ 
    FileStream stream = null; 
    try { 
     stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None); 
    } 
    catch (IOException) { 
     return true; 
    } 
    finally { 
     if (stream != null) 
      stream.Close(); 
    } 
    return false; 
} 
+0

這是最直接的解決方案,但我不想在我的代碼中使用更多的thread.sleeps。所以我正在使用其他方法 – satyajit 2011-03-09 06:20:04

+0

我正在編寫一個控制檯應用程序,並且這個工作完美。因爲我只有一個線程,所以我正在使用它。 +1。 – JohnP 2013-08-29 18:37:01

+0

也許增加檢查文件是否存在? – 2015-07-01 05:24:11

5

如果你堅持要用FileSystemWatcher你可能不得不考慮在一個單一的操作,有些大小的文件不被創建(上傳)的事實。在文件準備好使用之前,文件系統可能會生成1 created和x changed事件。

您可以捕獲created事件並創建新的(專用)線程(除非您已經有該文件的進行線程),並在其中循環並定期嘗試單獨打開該文件。如果你成功,文件就緒。

+0

這是絕對正確的。我一直在使用它來建立一個簡單的sFTP傳輸程序,甚至一個從根目錄複製到測試目錄的17k文件產生了1個創建的和4個更改的事件。 – JohnP 2013-08-29 18:38:32