2017-03-07 57 views
0
private void downloadFile(Int32 fileNr) 
     { 
      FileStream writer = null; 
      m_currentFileSize = 0; 
      fireEventFromBgw(Event.FileDownloadAttempting); 

      FileInfo file = this.Files[fileNr]; 
      FileInfo fileFirstDateTime = this.Files[0]; 
      FileInfo fileLastDateTime = this.Files[19]; 
      Int64 size = 0; 

      Byte[] readBytes = new Byte[this.PackageSize]; 
      Int32 currentPackageSize; 
      System.Diagnostics.Stopwatch speedTimer = new System.Diagnostics.Stopwatch(); 
      Int32 readings = 0; 
      Exception exc = null; 
      writer = LocalDirectorySettings(file); 
      HttpWebRequest webReq; 
      HttpWebResponse webResp = null; 

      try 
      { 
       webReq = (HttpWebRequest)System.Net.WebRequest.Create(this.Files[fileNr].Path); 
       webResp = (HttpWebResponse)webReq.GetResponse(); 

       size = webResp.ContentLength; 
      } 
      catch (Exception ex) { exc = ex; } 

      m_currentFileSize = size; 
      fireEventFromBgw(Event.FileDownloadStarted); 

      if (exc != null) 
      { 
       bgwDownloader.ReportProgress((Int32)InvokeType.FileDownloadFailedRaiser, exc); 
      } 
      else 
      { 
       m_currentFileProgress = 0; 
       while (m_currentFileProgress < size && !bgwDownloader.CancellationPending) 
       { 
        while (this.IsPaused) { System.Threading.Thread.Sleep(100); } 

        speedTimer.Start(); 

        currentPackageSize = webResp.GetResponseStream().Read(readBytes, 0, this.PackageSize); 

        m_currentFileProgress += currentPackageSize; 
        m_totalProgress += currentPackageSize; 
        fireEventFromBgw(Event.ProgressChanged); 
        try 
        { 
         writer.Write(readBytes, 0, currentPackageSize); 
        } 
        catch(Exception eee) 
        { 
         string myeee = eee.ToString(); 
        } 
        readings += 1; 

        if (readings >= this.StopWatchCyclesAmount) 
        { 
         m_currentSpeed = (Int32)(this.PackageSize * StopWatchCyclesAmount * 1000/(speedTimer.ElapsedMilliseconds + 1)); 
         speedTimer.Reset(); 
         readings = 0; 
        } 
       } 

       speedTimer.Stop(); 
       writer.Close(); 
       webResp.Close(); 
       if (!bgwDownloader.CancellationPending) { fireEventFromBgw(Event.FileDownloadSucceeded); } 
      } 
      fireEventFromBgw(Event.FileDownloadStopped); 
     } 

的bgwDownloader如何在文件下載完成後知道如何使用httpwebrequest和webresponse?

private BackgroundWorker bgwDownloader = new BackgroundWorker(); 

的DoWork的事件

private void bgwDownloader_DoWork(object sender, DoWorkEventArgs e) 
     { 
      Int32 fileNr = 0; 
      countFilesNames = 0; 

      if (this.SupportsProgress) { calculateFilesSize(); } 

      if (!Directory.Exists(this.LocalDirectory)) { Directory.CreateDirectory(this.LocalDirectory); } 

      while (fileNr < this.Files.Count && !bgwDownloader.CancellationPending) 
      { 
       m_fileNr = fileNr; 
       downloadFile(fileNr); 

       if (bgwDownloader.CancellationPending) 
       { 
        fireEventFromBgw(Event.DeletingFilesAfterCancel); 
        cleanUpFiles(this.DeleteCompletedFilesAfterCancel ? 0 : m_fileNr, this.DeleteCompletedFilesAfterCancel ? m_fileNr + 1 : 1); 
       } 
       else 
       { 
        fileNr += 1; 
       } 
      } 
     } 

在BackgroundWorker的完成的事件,它變得只有當所有的文件下載完成完成的事件。

但我需要爲每個文件下載完成創建事件。 這個問題如果我不需要使用backgroundworker或httpwebrequest webresponde以某種方式做到這一點?如何 ?

如果需要的話,我會上傳整個班級,有點長。

更新

這是在Form1我如何訂閱FileDownloadSucceeded事件:

downloader.FileDownloadSucceeded += new EventHandler(downloader_Succeeded); 

然後在事件

private void downloader_Succeeded(object sender, EventArgs e) 
     { 
      countFilesDownloaded++; 
      label6.Text = countFilesDownloaded.ToString(); 
      RichTextBoxExtensions.UpdateText(richTextBox1, "Ready: ", "Downloaded: ", Color.Green); 
     } 

問題是,當我把一個斷點事件中在最後一行RichTextBoxExtensions喜歡它一次到達那裏。下載的文件大小爲0字節。然後我再次繼續在此事件中停止,這次文件的大小已經完全下載或寫入。

所以我需要以某種方式檢查這個事件,當它完成下載完成。 我該怎麼做?

我想在這個事件中對下載的文件進行一些操作,但是我需要確保文件已經下載完畢,並且我現在用一個斷點檢查,並且只在第二次檢測到文件時完成下載/寫入硬盤。

更新

我主要在這裏的目標是我加入這個方法到Form1

public static Image[] GetFramesFromAnimatedGIF(Image IMG) 
     { 
      List<Image> IMGs = new List<Image>(); 
      int Length = IMG.GetFrameCount(FrameDimension.Time); 

      for (int i = 0; i < Length; i++) 
      { 
       IMG.SelectActiveFrame(FrameDimension.Time, i); 
       IMGs.Add(new Bitmap(IMG)); 
       IMG.Dispose(); 
      } 

      return IMGs.ToArray(); 
     } 

,我想每一個已下載的文件解壓/從文件中解析幀的GIF圖像的所有文件GIF動畫所以在FileDownloadSucceeded事件我前行補充說:

Image img = new Bitmap(downloader.fileName); 

事件

private void downloader_Succeeded(object sender, EventArgs e) 
     { 
      countFilesDownloaded++; 
      label6.Text = countFilesDownloaded.ToString(); 
      RichTextBoxExtensions.UpdateText(richTextBox1, "Ready: ", "Downloaded: ", Color.Green); 
      Image img = new Bitmap(downloader.fileName); 
     } 

在文件名中,我看到:C:\新建文件夾(3)\國家\歐洲\ 07032017_223558 \歐洲--- 07032017_223558384.gif

的文件是存在硬盤上。但我在這條線越來越異常:

Image img = new Bitmap(downloader.fileName); 

System.Reflection.TargetInvocationException was unhandled 
    HResult=-2146232828 
    Message=Exception has been thrown by the target of an invocation. 
    Source=mscorlib 
    StackTrace: 
     at System.RuntimeMethodHandle.InvokeMethod(Object target, Object[] arguments, Signature sig, Boolean constructor) 
     at System.Reflection.RuntimeMethodInfo.UnsafeInvokeInternal(Object obj, Object[] parameters, Object[] arguments) 
     at System.Delegate.DynamicInvokeImpl(Object[] args) 
     at System.Windows.Forms.Control.InvokeMarshaledCallbackDo(ThreadMethodEntry tme) 
     at System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj) 
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme) 
     at System.Windows.Forms.Control.InvokeMarshaledCallbacks() 
     at System.Windows.Forms.Control.WndProc(Message& m) 
     at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m) 
     at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m) 
     at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 
     at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) 
     at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) 
     at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) 
     at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) 
     at System.Windows.Forms.Application.Run(Form mainForm) 
     at DownloaderPro.Program.Main() in C:\Users\Chocolade\Documents\Visual Studio 2015\Projects\DownloaderPro\DownloaderPro\DownloaderPro\Program.cs:line 19 
     at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) 
     at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args) 
     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() 
     at System.Threading.ThreadHelper.ThreadStart_Context(Object state) 
     at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) 
     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) 
     at System.Threading.ThreadHelper.ThreadStart() 
    InnerException: 
     HResult=-2147024809 
     Message=Parameter is not valid. 
     Source=System.Drawing 
     StackTrace: 
      at System.Drawing.Bitmap..ctor(String filename) 
      at DownloaderPro.Form1.downloader_Succeeded(Object sender, EventArgs e) in C:\Users\Chocolade\Documents\Visual Studio 2015\Projects\DownloaderPro\DownloaderPro\DownloaderPro\Form1.cs:line 347 
      at DownloaderPro.FileDownloader.bgwDownloader_ProgressChanged(Object sender, ProgressChangedEventArgs e) in C:\Users\Chocolade\Documents\Visual Studio 2015\Projects\DownloaderPro\DownloaderPro\DownloaderPro\FileDownloader.cs:line 549 
      at System.ComponentModel.BackgroundWorker.OnProgressChanged(ProgressChangedEventArgs e) 
      at System.ComponentModel.BackgroundWorker.ProgressReporter(Object arg) 
     InnerException: 

這是BackgroundWorker的完整的類:

Class FileDownloader

這是我用winrar的項目:

Project

+1

你可能想看看BackgroundWorker的ReportProgress和OnReportProgress事件。它需要一個ProgressChangedEventArgs,它有一個名爲UserState的對象屬性,可以傳回信息(比如說一個字符串,表示「文件'X'已經完成下載」),所以當WebRequest完成時,引發ReportProgress。 –

回答

1

據我所知,在下載完成後,已經有一個事件發生。

fireEventFromBgw(Event.FileDownloadSucceeded) 

只需在創建背景工作時訂閱它即可。

編輯:

你只打了sln文件。在那裏看不到太多。 查看FileDownloader.cs的代碼後,它看起來像你沒有自己寫這個「怪物」。

我倒是想提出一個不同的approuch:

WebClient client = new WebClient(); 
client.DownloadFile(source, target); 

其中source爲URL和目標路徑在哪裏下載到。對於簡單的照片,它應該做的伎倆。這個approuch是同步的。

之後:

var frames = GetFramesFromAnimatedGIF(new Bitmap(target)); 

多個文件都放在一個循環。

+0

是的,我忘了提及我訂閱這個事件已經在Form1中了,我現在用這個部分更新了我的問題,如果你能在這個問題中看到我更新的部分,我現在使用了一個斷點,我發現了什麼問題,但不知道如何處理它。當它進入事件時,只有在第一次寫入文件或第一次完成文件下載時,纔會進入FileDownloadSucceeded文件,該文件爲9個字節或有時爲12kb或其他大小,但僅在第二次文件位於右側時大小 –

+0

現在我又試了一次,現在每次下載一個文件時它只會進入一次事件,而且文件似乎在硬盤上沒有問題,不知道是怎麼回事。我會再次更新我的問題,我的主要目標是什麼。 –

+0

好的,上次更新我的問題。對不起。現在我正在嘗試在事件中做什麼以及我得到了什麼異常。從一開始,整個問題就是例外。而且有時候它會進入事件並且下載的文件很好完成,但有時我會看到該文件的大小爲0字節,並且僅在第二次進入事件時文件沒有問題。不知道爲什麼。但是,如果我不在這個事件中使用斷點,並讓程序繼續工作,那麼所有的文件都可以正常工作。所以我想知道這個事件發生了什麼?以及如何解決它。 –

相關問題