hmmm i am getting a g@y error...i have 2events who share the same delegate..the param of the delegate and events is the class itself so it sends the class as param...hmm but only 1event is working!!! i cant understand why
(the thing that isn't working is in comment, it's the connectionStateChanged)
PHP Code:
using System;

namespace 
downloadClass
{
    
using System;
    
using System.Net;
    
using System.Threading;

    public class 
downloadManager
    
{
        
#region Vars
        
private string    _downloadAddress;
        private 
string    _downloadFolder;
        private 
double    _currentProgress = -1;
        private 
long    _fileSize = -1;
        private 
int        _downloaded = -1;
        private 
ConnectionState _connectionState 0;

        
/// <summary>
        /// Delegate used by this class
        /// </summary>
        
public delegate void downloadHandle(downloadManager e);

        
/// <summary>
        /// Ocorrs everytime the download progress is changed
        /// </summary>
        
public event downloadHandle progressChanged;
        
/// <summary>
        /// Returns the connection state within the connectionState enumerator
        /// </summary>
        
public event downloadHandle connectionStateChanged;

        
/// <summary>
        /// An enumeration with the possible connection states
        /// </summary>
        
public enum ConnectionState
        
{
            
Disconnected,
            
Connecting,
            
Connected,
            
Downloading,
            
Error,
            
DownloadComplete
        
}

        
/// <summary>
        /// The download url from where to download
        /// </summary>
        
public string downloadAddress
        
{
            
get
            
{
                return 
_downloadAddress;
            }
            
set
            
{
                
_downloadAddress value;
            }
        }

        
/// <summary>
        /// The download path
        /// </summary>
        
public string downloadFolder
        
{
            
get
            
{
                return 
_downloadFolder;
            }
            
set
            
{
                
_downloadFolder value;
            }
        }


        
/// <summary>
        /// The current progress of the download
        /// <returns>If the download still hasn't began then this method will return -1</returns>
        /// </summary>
        
public double currentProgress
        
{
            
get
            
{
                return 
_currentProgress;
            }
        }

        
/// <summary>
        /// The percentage of download
        /// <returns>Returns the size in kb and returns -1 if the download still hasn't began</returns>
        /// </summary>
        
public long fileSize
        
{
            
get
            
{
                return 
_fileSize;
            }
        }

        
/// <summary>
        /// Returns the file size of the already downloaded file
        /// </summary>
        
public int downloaded
        
{
            
get
            
{
                return 
_downloaded;
            }
        }

        public 
ConnectionState connectionState
        
{
            
get
            
{
                return 
_connectionState;
            }
        }

        
#endregion

        #region Constructors
        
public downloadManager()
        {
        }

        public 
downloadManager(string urlstring path)
        {
            
this._downloadFolder path;
            
this._downloadAddress url;
        }
        
#endregion
        
        /// <summary>
        /// Downloads a file to the hard drive
        /// </summary>
        
public void downloadFile()
        {
            
Thread thread = new Thread(new System.Threading.ThreadStart(t_downloadFile));
            
thread.Name this._downloadAddress;
            
thread.Start();
        }

        
/// <summary>
        /// Checks if a url has a known size
        /// </summary>
        
public bool urlHasKnownSize()
        {
                
#region Check Up
            
if (!(this._downloadAddress.StartsWith("http://") || this._downloadAddress.StartsWith("www.")))
            {
                throw (new 
System.Net.ProtocolViolationException("The provided url is not valid (" this._downloadAddress ")"));
            }
                
#endregion

            
HttpWebRequest wr = ((HttpWebRequest)WebRequest.Create(this._downloadAddress));
            
HttpWebResponse res = ((HttpWebResponse)wr.GetResponse());

            if (
res.ContentLength == -1)
            {
                return 
false;
            }
            else
            {
                return 
true;
            }
        }

        private 
void t_downloadFile()
        {
            
#region Check Up's
            
if (!(this._downloadAddress.StartsWith("http://") || this._downloadAddress.StartsWith("www.")))
            {
                throw (new 
System.Net.ProtocolViolationException("The provided url is not valid (" this._downloadAddress ")"));
            }

            
int pathPos this._downloadFolder.LastIndexOf(@"\");
            string path = this._downloadFolder.Substring(0, pathPos) + @"
\";

            if (!(System.IO.Directory.Exists(path)))
            {
                throw (new System.IO.DirectoryNotFoundException("
The provided path could not be found (" + this._downloadAddress + ")"));
            }
            #endregion

            HttpWebRequest wr = ((HttpWebRequest)WebRequest.Create(this._downloadAddress));
            HttpWebResponse res = ((HttpWebResponse)wr.GetResponse());
                
            this._connectionState = ConnectionState.Connecting;
            this._fileSize = res.ContentLength;
            //            this.connectionStateChanged(this);
            //            this.connectionStateChanged(this);

            System.IO.Stream streamIn = res.GetResponseStream();
            System.IO.FileStream streamOut = 
                new System.IO.FileStream(this._downloadFolder, System.IO.FileMode.Create);

            const int BUFFER_SIZE = 4096;
            byte[] buffer = new byte[BUFFER_SIZE];
            int iRead = streamIn.Read(buffer, 0, BUFFER_SIZE);
            int mRead = iRead;

            this._connectionState = ConnectionState.Connected;
            //            this.connectionStateChanged(this);

            while (iRead > 0)
            {
                streamOut.Write(buffer, 0, iRead);
                iRead = streamIn.Read(buffer, 0, 4096);
                mRead += iRead;
                this._downloaded = mRead;
                this._currentProgress = (double)mRead / (double)res.ContentLength * (double)100;
                this.progressChanged(this);
            }

            this._connectionState = ConnectionState.DownloadComplete;
            this.progressChanged(this);

            streamIn.Close();
            streamOut.Close();
        }
    }