2016-02-24 108 views
1

我的自定義類事件不起作用。 這裏是我的代碼:事件不起作用

public delegate void ChangedEventHandler(object sender, EventArgs e, int p); 

當我不使用delegate { },我得到錯誤:

Object reference not set to an instance of an Object.

public event EventHandler DownloadCompleted = delegate { }; 
public event ChangedEventHandler DownloadProgressChanged = delegate { }; 

public void DownloadFile(String url, String localFilename) 
{ 

    try 
    { 
     Application.DoEvents(); 
     WebRequest req = WebRequest.Create(url); 
     WebResponse response = req.GetResponse(); 
     Stream stream = response.GetResponseStream(); 
     byte[] downloadedData = new byte[0]; 

     int downloaded = 0; 

     byte[] buffer = new byte[1024]; 
     int totalData = (int)response.ContentLength; 
     int a = 0; 

     FileStream file = File.Create(localFilename); 

     while (true) 
     { 

      if (paused == false) 
      { 
       Application.DoEvents(); 
       int bytesRead = stream.Read(buffer, 0, buffer.Length); 

       if (bytesRead == 0) 
       { 
        file.Flush(); 
        file.Close(); 
        DownloadCompleted(this, new EventArgs()); 
        break; 
       } 
       file.Write(buffer, 0, bytesRead); 

       downloaded += bytesRead; 
       DownloadProgressChanged(this, EventArgs.Empty, downloaded); 
      } 
     } 
    } 

    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message.ToString()); 
    } 

} 

使用其他類這樣的:

Downloader dw = new Downloader(); 
dw.DownloadFile(txt_url.Text, txt_path.Text); 
dw.DownloadCompleted += dw_DownloadCompleted; 
dw.Changed +=dw_Changed; 

void wb_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e) 
{ 
    MessageBox.Show("Completed!"); 
} 

void wb_DownloadProgressChanged(object sender,DownloadProgressChangedEventArgs e) 
{ 
    //Setting ProgressBar Value 
    progressBar1.Maximum = 100; 
    progressBar1.Value = e.ProgressPercentage; 
} 

但ProgressBar無法正常工作。

我的代碼有什麼問題?

回答

3

你有調用 DownloadFile前分配事件處理程序在你的「其他」 類:

Downloader dw = new Downloader(); 
dw.DownloadCompleted += dw_DownloadCompleted; 
dw.Changed +=dw_Changed; 
dw.DownloadFile(txt_url.Text, txt_path.Text); 

你也不需要指定空的事件處理程序像= delegate { }

否則當DownloadFile試圖呼叫DownloadCompletedChanged事件處理程序 - 它們是空引用,這就是爲什麼你會得到該錯誤。指定空事件處理程序可防止NullReferenceException,但由於您將空事件處理程序分配給事件 - 它們顯然什麼都不做。

+3

OP在調用之前需要檢查'DownloadProgressChanged'是否爲null。不能保證會有任何訂閱者。在C#6中,問題可以通過將'DownloadProgressChanged(...)'更改爲'DownloadProgressChanged?.Invoke(this,...)'來解決。 –

+0

@PanagiotisKanavos在調用它之前,根本的錯誤並不是缺少對事件處理程序的檢查是空的(雖然這些檢查在OP代碼中真的缺失),但是分配事件處理程序和方法調用的順序不正確導致此處理程序爲空。 –

+0

沒有正確的分配事件處理程序的順序。可能沒有事件處理程序要分配 - 如果不想跟蹤進度,該怎麼辦?一個*有*在調用委託前檢查null。 –